使用向量(STL)时未定义的行为,请在原因后面解释下面的代码输出

int*_*aik 0 c++ stl vector

这个可能适用于某些编译器/操作系统,并与其他编译器崩溃.相同的代码与"列表"它工作正常,虽然只使用"向量"我面临未定义的行为输出.STL(矢量)是安全的??

注意:这不是一个实时代码,我只是通过一些示例程序来实现它.

#include <vector>
#include <iostream>

using namespace std;

int main() {
  vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  for (vector<int>::iterator i = v.begin();
       i != v.end(); i++) {
    cout << *i << endl;
    if (*i == 1) {
      v.push_back(5);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

向量输出:1 0 3 4 0 0 4113 0 858851888 943206709 2617..1 2 3 4 5 5

#include <list>
#include <iostream>

using namespace std;

int main() {
  list<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  for (list<int>::iterator i = v.begin();
       i != v.end(); i++) {
    cout << *i << endl;
    if (*i == 1) {
      v.push_back(5);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

列表输出:1 2 3 4 5

axa*_*lis 6

循环中的一行:

v.push_back(5);
Run Code Online (Sandbox Code Playgroud)

可能使迭代器无效i(在需要重新分配的情况下),因此从那时起++i是未定义的行为.

解决这个问题的一种可能性是首先保留向量,这样就不会发生重新分配:

  vector<int> v;
  v.reserve(5); // reserve enough to keep all the pushed items
  v.push_back(1);
  ...
Run Code Online (Sandbox Code Playgroud)

  • 无效保证无效; 只有重新分配发生时才会这样. (2认同)