vpuente
vpuente

Reputation: 932

How to handle correctly/efficiently pointers to std::vector elements?

Let say we have:

std::vector<Segment*> segments;
...
Segment* dd = new Segment;
segments.emplace_back(dd);
Owner*   owner = getOwner();
owner->setSegmentPointer(&(segments.back());

This will not work because of Iterator invalidation rules.

Any subsequent element addition to the vector segments will render invalid the pointers stored in owner. How to circumvent this problem keeping the access time of std::vector<>? (Assuming that we can't use vector.resize in advance). Is to use std::map<> the only solution?

Thanks in advance

Upvotes: 0

Views: 285

Answers (2)

Aconcagua
Aconcagua

Reputation: 25536

Each owner can use that pointer to access other elements in the vector.

Apart from being a horrible idea, you could realise it with a std::list, though:

First, every owner instance gets an iterator to the list, not a pointer to a segment. std::list has the advantage of not invalidating iterators on insertion/deletion, unless you delete the element an iterator points to.

Via this iterator, you can find the other elements in the list. One problem remains, though: you need to detect safely the begin and end of the list. So you need sentinel values at begin and end, which could be e. g. null pointers, if these do not occur in the list.

One important note: If you need to remove a segment from the list, although an owner still has an iterator to it, you need to find a way to inform the owner about iterator invalidation. There are no means available to get this done automatically!

Upvotes: 2

NathanOliver
NathanOliver

Reputation: 180935

If you need random access but you need the container to grow without invalidating pointers/references/iterators to the elements then you can use a std::deque. This will let you grow/shrink from the front or back. If you insert/erase from the middle though that can still invalidate iterators.

Upvotes: 1

Related Questions