请解释为什么以下代码按预期工作(元素添加到第二个位置):
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
答案 0 :(得分:6)
这是未定义的行为。 std::vector::reserve
不会调整向量的大小,因此调用v[i]
是一种超出范围的访问权限。
您需要调用v.resize(5)
展开向量以容纳5个元素,或者在循环内调用v.push_back
。
答案 1 :(得分: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个元素保留空间,这些元素按顺序插入(当你事先知道你有多少个元素时,这通常会被使用,但每个元素不需要知道要插入什么索引 - 每个一个只是被添加到向量的末尾。
注意,在任何一种情况下,您仍然可以添加其他项目 - 矢量将调整大小。为了保持代码的最佳状态,我们的目标是尽量减少向量调整大小的次数。