我试图清除()一个嵌套的向量,而不是被清除,向量填充了我的计算机的所有内存。 以下是重现行为的代码:
#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包含至少两个等于元素,那么这个奇怪的行为就会发生。 所以有两个问题: 您是否在计算机上观察到相同的行为? 你明白为什么吗?
答案 0 :(得分:2)
std::vector::clear
将破坏所有元素:
从容器中删除所有元素。
使引用包含元素的任何引用,指针或迭代器无效。任何过去的迭代器也都会失效。
您无法通过向量的末尾访问数据,并期望发生任何理智。这显然是UB。
访问未分配的数据可能会导致返回0.但是,无法保证代码显示UB时会发生什么。对于如何以不同方式访问数据会产生不同结果的推理没有用处,它完全不确定。
尝试使用边界检查代码迭代向量,例如:
std::vector<std::vector<std::vector<int>>> v(2, std::vector<std::vector<int>>(2, std::vector<int>{}));
//v.clear();
for (auto&& v1 : v) {
for (auto&& v2 : v1) {
std::cout << v2.size() << std::endl;
}
}
现在,取消注释clear()
语句并查看您获得的打印输出数量。
答案 1 :(得分:1)
清除矢量,然后尝试使用索引进行迭代。你期望发生什么?如果v.at(x)
,请尝试使用v[x]
,看看会发生什么