【问题标题】:Unexpected results when calling resize() on an STL vector in C++在 C++ 中对 STL 向量调用 resize() 时出现意外结果
【发布时间】:2013-09-11 08:12:20
【问题描述】:

在下面的代码中,如果我调用v.resize(n),程序会打印出0 0 0 0 0 0 0 0 0 0,这不是我想看到的。但是,如果我将包含 v.resize(n) 的行注释掉,它将打印出 0 1 2 3 4 5 6 7 8 9,这正是我想看到的。为什么会这样?我这里的逻辑有什么问题?

#include <iostream>
#include <vector>

using namespace std;

int main( int argc , char ** argv )
{
    int n = 10;
    vector<int> v;
    v.resize(n);

    for( int i=0 ; i<n ; i++ )
    {
        v.push_back(i);
    }

    for( int i=0 ; i<n ; i++ )
    {
        cout << v[i] << " ";
    }

    cout << endl;

    return 0;
}

【问题讨论】:

  • 当您对容器的内容感到困惑时,不要假设您知道它的大小。不要从0 循环到n 来显示内容,而是使用迭代器并从begin() 循环到end()
  • 也许您打算改用.reserve

标签: c++ vector stl containers


【解决方案1】:

resize 确保向量恰好包含n 元素,而push_back 将项目附加到vector,因此在调整大小后占据向量的零之后添加数字。如果您打印向量 (&lt; v.size()) 中的所有数字,而不是仅打印第一个 n,您可以看到它。

表现如您预期的方法是reserve()

效果: 一个指令,通知向量计划的大小变化,以便它可以相应地管理存储分配。在reserve()之后,如果发生重新分配,capacity()大于或等于reserve的参数;并且等于之前的值 capacity() 否则。当且仅当当前容量小于reserve() 的参数时,才会在此时发生重新分配。如果非 CopyInsertable 类型的移动构造函数引发异常,则没有任何影响。 (§23.3.6.3/2)

【讨论】:

    【解决方案2】:

    v.push_back(i) 将向量 v 的大小增加 1,其中 i 是该向量中最后一个元素的值。这就是为什么在向量的开头(即前面)保留 10 个零的原因。

    你应该改写v[i] = i

    无论您做什么,都不要删除v.resize(n); 行并保留您的push_back,因为分段调整向量的大小不是最佳的 - 由于内存重新分配。 (虽然好的 stl 会针对此类编程进行优化,但最好不要依赖它)。

    【讨论】:

    • 好吧,用reserve替换resize也是一种选择,这可能会导致OP预期的行为。
    • @Hulk:同意:当然,如果他放弃了resize1,就可以了;并且不会发生内存重新分配。
    【解决方案3】:

    vector.resize()

    调整容器大小,使其包含 n 个元素。

    您正在将其大小调整为 n (10)。所以现在它有十个 0。然后在列表末尾添加十个 更多 数字(0 到 9)(通过 push_back())。最后,您只打印出第一个 n (10),它们仍然全为零。

    您的程序正在按照您的要求执行。

    【讨论】:

    • 我明白了。所以我必须使用 [] 运算符来赋值,对吧?
    • @takwing:是的,否则使用reserve(),它只保留在向量调整大小时使用的内存。
    • @tawking 如果你想替换你已经放入向量中的零,是的。
    猜你喜欢
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    相关资源
    最近更新 更多