我读过这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());
}
Run Code Online (Sandbox Code Playgroud)
我希望这能给我一些数字的向量和这些数字的指针向量.但是,当列出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;
}
Run Code Online (Sandbox Code Playgroud)
结果看起来大致如下:
1
some random number
2
some random number
some random number
3
Run Code Online (Sandbox Code Playgroud)
因此,当我push_back()对numbers向量时,它的旧元素似乎改变了它们的位置.
那究竟是什么意思呢,这std::vector是一个连续的容器,为什么它的元素会移动?是否可以将它们存储在一起,但是当需要更多空间时将它们一起移动?
编辑:std::vector仅在C++ 17之后是连续的吗?(只是为了保留对我之前的声明的评论与未来的读者相关.)
假设我们有以下课程:
class Test {
public:
Test() {}
std::vector<int>& getIntList() {
return intList;
}
private:
std::vector<int> intList;
};
Run Code Online (Sandbox Code Playgroud)
同样,我们在main函数中有以下代码来声明类数组:
int main(void) {
Test* test[20];
for (int i = 0; i < 20; ++i) {
test[i] = new Test();
}
}
Run Code Online (Sandbox Code Playgroud)
在这些情况下,将实例化测试对象。
现在,如果我在每个类中的向量中随机添加多个项目,
在调整其内存大小的同时,可能会碰撞每个类中每个向量的内存地址范围。
在这种情况下,是否将整个“测试”对象复制到其他存储区中,并调整矢量的大小?或者,向量STL是仅在类引用向量时才复制到其他存储区并调整大小吗?
完全地,这样编码不是一个好主意吗?
我想我的问题不需要最小的工作示例;这可能很容易并且易于描述。
让我们假设有一个类实例将一些对象存储为成员。现在其中一个成员在运行时增长。创建实例后,member1 消耗了 10 个字节,member2 消耗了 20 个字节。然后 object1 以某种方式被修改,现在需要 15 个字节。
我的问题是,member1(的第一个字节)的地址是否不变?或者,member1 的第一个字节现在有可能像以前一样有另一个地址吗?成员变量是否在堆中分配?
感谢您的反馈意见!
最好的事物