嵌套c++向量的重新定位

Reallocation of nested c++ vectors

本文关键字:定位 新定位 c++ 向量 嵌套      更新时间:2023-10-16

假设我们有一个包含std::vector容器的结构:

struct A {
    char a;  // decoration
    vector<int> v;
    A() {}
};

在我们的代码中的某个时刻,我们有一个std::vector存储这些A结构(也就是说,两个级别的std::vectors),然后,我们在它的一个元素上为v保留更多的内存空间:

    /*...*/
    vector<A> vect;
    vect.resize(10, A());
    vector<A>* vect_ptr = &vect;
    vect[0].v.reserve(9999999);
    cout << vect_ptr << " ?= " << &vect << endl;
    /*...*/

问题是:在为其中一个"低级"向量v保留空间后,是否存在"高级"向量vect被重新分配,使指针vect_ptr无效的风险?

在肯定的情况下,将v重新定义为参考是否是解决方案?(即使它增加了间接级别):

struct A {
    char a;
    vector<int>& v;
    A() : v(vector<int>()) {}
};

否。不存在这样的风险。

vect拥有一些内存,它在其中写入了一堆A:所以可能在内存中有这样的东西:

[--A--][--A--][--A--]...[--A--]
^                       ^
&vect[0]                &vect[9]

但这些A中的每一个都有一些向量,指向其他地方的更多内存。以下是vect[1].v可能指向的粗略说明:

         [int][int][int][int][int]...
         ^
         |
[--A--][--A--][--A--]...[--A--]
^                       ^
&vect[0]                &vect[9]

(我为可怕的ascii艺术道歉)

这两个容器拥有它们自己的内存,这些内存不重叠。调整其中一个"内部"向量的大小可能会改变它拥有的内存,但这与vect拥有的内存无关(除非分配器严重损坏,而std::allocator不是)。您可以将vect的内存视为完全禁止其他任何东西尝试分配的内存。在一个"内部"向量中尝试分配多少并不重要。在某些情况下,您将无法分配那么多内存,但永远不会有重新分配任何其他对象的风险。

也许吧。我认为标准实际上并不能保证这一点。它是实现定义的,应该适用于std::vector的大多数实现。但这不是你可以信赖的

也许迭代器具有引用原始容器的传统调试信息——你会遇到麻烦。