【发布时间】:2018-06-28 22:57:52
【问题描述】:
我试图 clear() 一个嵌套向量,但该向量没有被清除,而是填满了我计算机的所有内存。 这是重现该行为的代码:
#include <iostream>
#include <vector>
using namespace std;
main(int argc, char* argv[]){
int d, j;
int D = 2;
vector<int> N = {2,2};
vector<vector<vector<int>>> v;
v.resize(D);
for(d = 0; d < D; d++)
v[d].resize(N[d]);
v.clear();
for(d = 0; d < D; d++)
for(j = 0; j < N[d]; j++)
cout << "d : " << d << ", j : " << j << ", v[d][j].size() : " << v[d][j].size() << endl;
}
我在 x86_64-linux-gnu 上使用 gcc 版本 5.4.1 并使用
进行编译g++ -std=c++17 freeing_vector.cpp && ./a.out
其中 freeing_vector.cpp 是我之前给出的代码。 输出如下:
d : 0, j : 0, v[d][j].size() : 0
d : 0, j : 1, v[d][j].size() : 0
d : 1, j : 0, v[d][j].size() : 18446744073707429092
d : 1, j : 1, v[d][j].size() : 0
现在有趣的部分是:请确认删除 v.clear() 会产生预期的结果。 然后尝试用D不同的数字改变N的内容,比如
N = {3, 4};
在我的电脑上不会出错。一般来说,无论 D 是什么,在我看来,如果 N 包含至少两个等于元素,就会发生这种奇怪的行为。 所以两个问题: 您是否在计算机上观察到相同的行为? 你明白为什么吗?
【问题讨论】:
-
v[0]是向量为空时未定义的行为。之后的一切都是无关紧要的。 -
您发现未定义的行为很难推理。 UB 可以做任何事情,最令人头疼的 UB 是代码似乎可以完美运行,直到您最大的客户在他们最重要的生产日午夜崩溃。这就是存在静态和动态代码分析工具的原因