std::vector 的替代方案,因为重新分配会使指向元素的指针无效

Alternatives to std::vector due to reallocation that invalidates pointers to elements

本文关键字:分配 元素 无效 指针 新分配 vector 方案 std 因为      更新时间:2023-10-16
这可能是

一个新问题(我是),但我已经尽可能多地搜索以找到以下问题的解决方案

我有以下情况(当然是大量蒸馏):

class Container
{
std::vector<Object> obj;
};
class Pointers
{
std::vector<Object*> obj_ptr;
};

我有一个例程,它将 Object 类型的元素推回容器中的矢量 obj,然后将指向同一元素的指针推回 obj_ptr

总体思路是obj_ptr[i] == &obj[i] 贯穿程序的整个生命周期。

我遇到的问题是,每当 obj 的容量需要增加时,所有指针都会失效,使obj_ptr完全无用。我已经尝试了使用最大预期大小(大约 10^7)的 obj.reserve() 和以相同的大小初始化向量。问题仍然存在。

不确定它是否重要,但我使用的是VS 2015 Com。

谢谢!

常见的替代方案是使用智能指针,例如

class Container {
    std::vector<std::unique_ptr<Object>> obj;
};

class Container {
    std::vector<std::shared_ptr<Object>> obj;
};

取决于您的用例(语义上)。

Boost 稳定矢量就是为此而设计的。它是一个向量(在 O(1) 等中访问),不会使其值无效。它符合标准C++容器 API/语义。

它类似于std::vector<std::unique_ptr<T>>,但隐藏了智能指针。

您可以在 Container 中使用 std::liststd::forward_list,以便指针不会失效。

class Container
{
std::forward_list<Object> obj;
};
class Pointers
{
std::vector<Object*> obj_ptr;
};

不过,请注意从obj中删除元素的过程。从obj中删除元素会使 obj_ptr 中的相应指针失效。

你有很多选择

  • 使用std::liststd::deque等数据结构,其中添加元素不会使指向先前添加元素的指针失效。

  • 在第二个数组中保留索引而不是指针

  • 只有指针向量 - 可能是第一个数组的std::vector<std::unique_ptr<Object>>,其他数组std::vector<Object *>,或者可能是所有数组的std::vector<std::shared_ptr<Object>>

哪个最有意义取决于您实际要做什么。