简体   繁体   English

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

[英]Alternatives to std::vector due to reallocation that invalidates pointers to elements

this might be a newb question (i am) but i've searched as much as i could to find a solution to the following problem 这可能是一个新问题(我),但我已尽可能多地搜索以找到解决以下问题的方法

I have the following scenario (heavily distilled of course): 我有以下场景(当然很重要):

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

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

I have a routine that pushes back an element of type Object to the vector obj in Container then pushes back the pointer to that same element to obj_ptr . 我有一个例程,它将Object类型的元素推回到Container中的向量obj ,然后将指向同一元素的指针推回到obj_ptr

the overall idea is that obj_ptr[i] == &obj[i] throughout the life of the program. 整个想法是obj_ptr [i] == &obj [i]在整个程序的整个生命周期。

The problem I run into is that whenever the capacity of obj needs to increase all the pointers are invalidated, making the obj_ptr completely useless. 我遇到的问题是,每当obj的容量需要增加所有指针都无效时,使obj_ptr完全无用。 I have tried both obj.reserve() using the maximum expected size (around 10^7) and initializing the vector with that same size. 我使用最大预期大小(大约10 ^ 7)尝试了两个obj.reserve()并初始化具有相同大小的向量。 Problem still persists. 问题仍然存在。

Not sure if it's important, but I'm using VS 2015 Com. 不确定它是否重要,但我正在使用VS 2015 Com。

Thanks! 谢谢!

The common alternative is using smart pointers like 常见的替代方案是使用智能指针

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

or 要么

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

Depends on your use case (semantically). 取决于您的用例(语义)。

Boost stable vector is designed for this. 为此设计了Boost稳定矢量 It is a vector (access in O(1), etc.) which does not invalidate its values. 它是一个向量(在O(1)等中访问),它不会使其值无效。 It is complying to the standard C++ container API/semantic. 它符合标准C ++容器API /语义。

It is similar to a std::vector<std::unique_ptr<T>> but hides the smart pointer from you. 它类似于std::vector<std::unique_ptr<T>>但隐藏了智能指针。

You can use std::list or std::forward_list in Container , so that the pointers are not invalidated. 您可以在Container使用std::liststd::forward_list ,以便指针不会失效。

class Container
{
std::forward_list<Object> obj;
};

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

Pay attention to the process of deleting elements from obj , though. 但是要注意从obj中删除元素的过程。 Deleting an element from obj does invalidate the corresponding pointer in obj_ptr . obj 删除元素会使obj_ptr的相应指针无效。

You have a number of choices 你有很多选择

  • Use a data structure like std::list or std::deque where adding elements does not invalidate pointers to previsouly added elements. 使用像std::liststd::deque这样的数据结构,其中添加元素不会使指向预先添加的元素的指针无效。

  • keep indexes instead of pointers in your second array 在第二个数组中保留索引而不是指针

  • have only vectors of pointers -- perhaps a std::vector<std::unique_ptr<Object>> for the first array and std::vector<Object *> for the others, or perhaps std::vector<std::shared_ptr<Object>> for all the arrays. 只有指针的向量 - 可能是第一个数组的std::vector<std::unique_ptr<Object>>和其他的std::vector<Object *> ,或者std::vector<std::shared_ptr<Object>>所有数组的std::vector<std::shared_ptr<Object>>

Which makes the most sense depends on what it is you are actually trying to do. 哪个最有意义取决于你实际上想要做什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM