【发布时间】:2019-02-19 03:37:39
【问题描述】:
我读到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 是一个连续的容器究竟是什么意思,为什么它的元素会移动?它是否可能将它们存储在一起,但在需要更多空间时将它们一起移动?
编辑:std::vector 是否仅从 C++17 开始连续? (只是为了让我之前的声明中的 cmets 与未来的读者相关。)
【问题讨论】:
-
vector 必须遵守其保证元素连续的承诺,这意味着如果 vector 必须将元素移动到更大的空间,它会这样做。 -- 我知道,std::vector 仅在 C++17 之后才成为连续容器 -- 自 1998 年以来一直是连续的。
-
这是我在 cppreference 上读到的:std::vector(用于 T 而非 bool)满足 Container、AllocatorAwareContainer、SequenceContainer、ContiguousContainer(自 C++17 起)和 ReversibleContainer 的要求。跨度>
-
@McSim 这些只是现在使用的官方名称。始终保证
std::vector将其项目存储在连续的内存中。非正式地它是连续的,因为标准中有一个缺陷没有说明它是连续的。然后(如果我记得的话),缺陷在 03 标准中得到纠正。 -
如果要观察连续内存的效果,请提前使用
reserve。 -
@PaulMcKenzie 感谢您的解释。
标签: c++ memory vector contiguous