c++ - 在内存中,C++ 看起来像什么?

  显示原文与译文双语对照的内容
110 0

我知道 std::vector 应该是连续的。我的理解是,它的元素应该存储在一起,而不是分散在内存中。我只是接受了这个事实,并使用了这个知识,例如使用它的data() 方法来获取底层的内存。

但是,我遇到了一种情况,其中向量的内存以一种奇怪的方式运行:

std::vector<int> numbers;
std::vector<int*> ptr_numbers;
for (int i = 0; i <8; i++) {
 numbers.push_back(i);
 ptr_numbers.push_back(&numbers.back());
}

我希望这个能给我一些数字向量和指向这些数字的向量向量。但是,当列出 ptr_numbers 指针的内容时,有不同的和似乎随机的数字,就像我正在访问错误的部分。

我每一步都试图检查内容:

for (int i = 0; i <8; i++) {
 numbers.push_back(i);
 ptr_numbers.push_back(&numbers.back());
 for (auto ptr_number : ptr_numbers)
 std::cout <<*ptr_number <<std::endl;
 std::cout <<std::endl;
}

结果大致如下:

1
some random number
2
some random number
some random number
3

因这里似乎当 push_back()numbers 向量时,它的老元素会改变它们的位置。

那它是什么意思,std::vector 是一个连续的容器,为什么要移动它的元素?当需要更多空间时,它是否会将它们一起存储,但将它们全部移动到一起?

时间:原作者:0个回答

52 2

它大致看起来像这个( 请原谅我的Paint杰作):

vector memory layout

堆栈上的std::vector 实例是一个小对象,它的中包含一个指向堆的指针,以及一些额外的变量。

因这里似乎当 push_back()numbers 向量时,它的老元素会改变它们的位置。

分配的缓冲区具有固定容量。当到达缓冲区末尾时,就会在堆的其他地方分配一个的新缓冲区,所有之前的元素都将被移动到新的缓冲区。因此他们的地址将会改变。

当需要更多空间时,它是否会将它们一起存储,但将它们全部移动到一起?

基本上是,只有当不进行重新分配时,元素的迭代器和地址稳定性才会得到保证,只有

我知道,std::vector 只是一个连续的容器,因为 C++17

std::vector的内存布局自第一次出现以来没有发生更改。ContiguousContainer 只是在编译时将连续容器与其他容器区分开来的一个"概念"。

原作者:
...