C ++:清除嵌套向量会导致奇怪的结果

时间:2018-01-19 16:30:19

标签: c++ vector

我试图清除()一个嵌套的向量,而不是被清除,向量填充了我的计算机的所有内存。 以下是重现行为的代码:

#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包含至少两个等于元素,那么这个奇怪的行为就会发生。 所以有两个问题: 您是否在计算机上观察到相同的行为? 你明白为什么吗?

2 个答案:

答案 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],看看会发生什么