1

I want to have a place to store my objects. A vector is a good choice for this but I also want to pass a pointer to those elements to other objects. The problem is that when I push_back, the vector might invalidate all the references...

Should I use a vector of shared_ptr? And store a shared_ptr in my other objects so when the vector grows, the shared_ptr is still valid? This seems costly because I have many objects to store.

The vector or any container that will contains the object is the person who owns the objects. Now I just want to have a stable reference or something to those elements that I can pass around to other people.

Jojolatino
  • 696
  • 5
  • 11
  • _"the vector might invalidate all the references"_ Which references are you talking about? If you need to store references then use some suitable class to represent the referenced object, e.g. a `std::shared_ptr` to be stored in the vector (or another container). – πάντα ῥεῖ Jan 10 '21 at 09:01
  • @πάνταῥεῖ I guess that's about pointers/references to the insides of the vercor that were passed to other objects. – n. m. could be an AI Jan 10 '21 at 09:03
  • Possible duplicate of [Any way to update pointer/reference value when vector changes capacity?](https://stackoverflow.com/questions/58517909/any-way-to-update-pointer-reference-value-when-vector-changes-capacity/58518170) – NotAProgrammer Jan 10 '21 at 09:04
  • If the vector owns the objects, it should be unique_ptr, not shared_ptr (and your objects should be getting a plain dumb pointer). – n. m. could be an AI Jan 10 '21 at 09:04
  • 1
    By using (smart) pointers, each object will be in a separate memory location, which might be quite inefficient (dynamic memory allocations, prefetching, heap housekeeping data, etc.). I would prefer to either switch to `std::deque`, or keep using `std::vector` but store _indexes_ of elements instead of references/pointers/iterators. – Daniel Langr Jan 10 '21 at 09:04
  • @n.'pronouns'm. As the OP already seems to grasp, it's a very bad idea to rely on the addresses of value type items stored in a c++ standard container. That's what smart pointers or stuff like `std::reference_wrapper` are for. – πάντα ῥεῖ Jan 10 '21 at 09:06
  • @DanielLangr std::deque is good if you only push and pop, never insert or erase in the middle. – n. m. could be an AI Jan 10 '21 at 09:07
  • @n.'pronouns'm. _"The problem is that when I `push_back`, the vector might invalidate all the references..."_ — According to this notice, I suppose OP does not insert elements in the middle. But cannot be sure, of course. – Daniel Langr Jan 10 '21 at 09:10
  • @πάνταῥεῖ It is not a bad idea for every container, just for std::vector and allies. Linked lists and associative containers never move elements around. – n. m. could be an AI Jan 10 '21 at 09:12
  • @n.'pronouns'm. Well the `std::list` and `std::forward_list` containers are suitable for this, but there are other drawbacks with these, that might weigh out the tiny difference, (overhead) a `std::shared_pointer` has over a raw pointer. – πάντα ῥεῖ Jan 10 '21 at 09:15
  • @πάνταῥεῖ this doesn't need a shared pointer, but a unique pointer (if we agree that the container should own the members). A unique pointer has virtually no overhead over a raw pointer. However, a pointer has an overhead over no pointer, so this needs to be measured. I think std::list has no chance of outperforming a vector of pointers, but std::unordered_set just might. – n. m. could be an AI Jan 10 '21 at 09:19
  • @n.'pronouns'm. _"if we agree that the container should own the members"_ Sure I'd agree with that, but it's the OP who must tell their needs in more detail here, right? – πάντα ῥεῖ Jan 10 '21 at 09:22
  • @πάνταῥεῖ If the zeroth-approximation solution is storing objects in the container directly, then the container owns them. – n. m. could be an AI Jan 10 '21 at 09:32
  • 1
    In what way does passing around the index not solve your problem? – acraig5075 Jan 11 '21 at 06:36
  • @acraig5075 From the point of view of my external objects, they want a pointer, they don't want to have an index and know where the array containing the objects is. So you are saying that because of weird reference invalidation of vectors, I can't store a pointer to one of the element? Coulnd't we imagine a memory space that is fixed, and if I push_back and exceed the current size, allocate a new memory space but keeping the old one? – Jojolatino Jan 11 '21 at 09:03

0 Answers0