【问题标题】:c++ vector insert unexpected behaivorc++向量插入意外行为
【发布时间】:2013-12-12 13:56:06
【问题描述】:

请解释为什么以下代码按预期工作(元素添加在第 2 位):

std::vector<int> v(5);

for(int i = 0; i < 5; i++)
    v[i] = i;

std::vector<int>::iterator it = v.begin()+1;
it = v.insert(it, 33);

cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
//outs: 0 33 1 2 3

以下没有(元素被添加到第一个位置):

std::vector<int> v;
v.reserve(5);

for(int i = 0; i < 5; i++)
    v[i] = i;

std::vector<int>::iterator it = v.begin()+1;
it = v.insert(it, 33);

cout << v[0] << " " << v[1] << " " << v[2] << " " << v[3] << " " << v[4] << endl;
//outs: 33 1 2 3 4

【问题讨论】:

  • 你的意思是resize()而不是reserve()

标签: c++ vector insert


【解决方案1】:

这是未定义的行为。 std::vector::reserve 不会调整向量的大小,因此调用 v[i] 是越界访问。

您需要调用 v.resize(5) 来扩展向量以容纳 5 个元素,或者在循环内调用 v.push_back

【讨论】:

    【解决方案2】:
    std::vector<int> v(5);
    

    创建一个 5 元素向量

    std::vector<int> v;
    v.reserve(5);
    

    创建一个空向量,但分配空间以稍后推回 5 个元素

    所以尝试访问v[i] 是未定义的行为,因为此时向量实际上不包含任何元素。

    您的第二个示例可以更改为:

    std::vector<int> v;
    v.resize(5);
    
    for(int i = 0; i < 5; i++)
        v[i] = i;
    

    这会正确创建一个 5 元素向量(当您最初不知道分配向量时的大小时,可以使用它)

    std::vector<int> v;
    v.reserve(5);
    
    for(int i = 0; i < 5; i++)
        v.push_back(i);
    

    为 5 个元素保留空间,这些元素按顺序插入(当您事先知道有多少元素时,通常会使用此方法,但每个元素不需要知道要插入的索引位置 - 每个一个只是被添加到向量的末尾。

    请注意,在任何一种情况下,您仍然可以添加其他项目 - 向量只会调整大小。为了让您的代码保持最佳状态,我们的目标是尽量减少矢量的大小调整次数。

    【讨论】:

    • std::vector&lt;int&gt; v(5); 执行自动v.resize(5);,对吗?除了push_back,还有什么方法可以添加元素吗?
    • 是的,构造函数版本在开始时会调整 vector 的大小。有多种方法可以将项目添加到 vector - 您已在原始帖子中包含其中两个 - [] 运算符将允许您重新分配 vector 中的元素。 insert 允许您在中间添加一个新项目,push_back 允许您在最后添加一个。其他容器,比如deque也有push_front
    • 谢谢,有没有办法将元素添加到我使用的向量 reserve(n); 除了 push_back,因为 push_back 很慢。
    • 保留后 push_back 会加快速度吗?有多慢?
    • @SkyRipper:如果你已经使用reserve() 设置了足够的capacity(),那么push_back() 只是在保留空间中构造新元素(不重新分配整个向量)。
    猜你喜欢
    • 1970-01-01
    • 2015-10-02
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    相关资源
    最近更新 更多