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

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-04 19:06:20

问题


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.

the overall idea is that obj_ptr[i] == &obj[i] throughout the life of the program.

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. I have tried both obj.reserve() using the maximum expected size (around 10^7) and initializing the vector with that same size. Problem still persists.

Not sure if it's important, but I'm using VS 2015 Com.

Thanks!


回答1:


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).




回答2:


Boost stable vector is designed for this. It is a vector (access in O(1), etc.) which does not invalidate its values. It is complying to the standard C++ container API/semantic.

It is similar to a std::vector<std::unique_ptr<T>> but hides the smart pointer from you.




回答3:


You can use std::list or std::forward_list in Container, so that the pointers are not invalidated.

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. Deleting an element from obj does invalidate the corresponding pointer in obj_ptr.




回答4:


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.

  • 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.

Which makes the most sense depends on what it is you are actually trying to do.



来源:https://stackoverflow.com/questions/35683652/alternatives-to-stdvector-due-to-reallocation-that-invalidates-pointers-to-ele

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!