分配std :: vector元素的两种方法

时间:2019-05-10 11:37:58

标签: c++

据我所知,可以通过两种方式将元素分配给std::vector

vec[i] = value

vec.push_back(value)

但是,第一种方法似乎对vec.size()没有影响,并且随后的对vec.push_back()的调用也将其覆盖。一个最小的例子来演示:

#include <iostream>
#include <vector>

int main()
{
    std::vector<unsigned char> things;
    things.reserve(2);

    things[0] = 'a';
    std::cout << "Size after inserting a: ";
    std::cout << things.size() << std::endl;

    things.push_back('b');
    std::cout << "Size after inserting b: ";
    std::cout << things.size() << std::endl;

    std::cout << "Contents: ";
    for (int i=0; i<2; i++)
    {
        std::cout << things[i] << std::endl;
    }

    return 0;
}

该程序的输出为:

Size after inserting a: 0
Size after inserting b: 1
Contents: b

所以有人可以解释一下吗?

  1. 为什么即使插入'a'后大小仍为0?

  2. things.push_back('b')为什么覆盖'a'

注意:我使用unsigned char是因为我已经从正在编写的涉及操纵该类型的程序中改编了这段代码。

谢谢。

3 个答案:

答案 0 :(得分:7)

reserve实际上并没有改变向量的大小。它仅改变向量的容量-不同于向量的实际大小(有关其实际含义的说明,请参见here)。因此,您对things[0] = 'a';的调用超出了向量的大小,因为它的大小仍然为0,因此行为未定义。

如果您致电resize,则会收到以下提示:

Size after inserting a: 2
Size after inserting b: 3
Contents: a

现在,向量包含'a''\0''b'。之所以使用'\0'是因为这是unsigned char的默认值,因此在将things.resize(2);更改为'a'之前,pd.concat(to_concat, axis=1) 会将矢量留给其中的两个。

答案 1 :(得分:5)

  1. 您没有插入它,而是分配给了一个不存在的元素。这具有不确定的行为。分配不会扩展向量。
  2. 由于向量为空,因此push_back添加了第一个元素。

答案 2 :(得分:0)

更多信息

std::vector<unsigned char> things;
things.reserve(2);

在赋值之下,如果不检查向量的界限,它将写入事物[0]指向的内存中。此操作永远不会失败,但是会由于内存损坏而导致未定义的行为。

things[0]    = 'a';  // 1

在写入事物[0]指向的内存之前,在向量的赋值检查边界之下。如果索引不在向量的范围内,则失败,并抛出“ std :: out_of_range”异常。

things.at(0) = 'a'   //2
相关问题