Pointers to Elements of Std::Vector and Std::List

Pointers to elements of std::vector and std::list

Vectors - No. Because the capacity of vectors never shrinks, it is guaranteed that references, pointers, and iterators remain valid even when elements are deleted or changed, provided they refer to a position before the manipulated elements. However, insertions may invalidate references, pointers, and iterators.

Lists - Yes, inserting and deleting elements does not invalidate pointers, references, and iterators to other elements

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

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!

getting pointers to vector elements

When a new element is added to a vector then the vector can be reallocated. So the previous values of pointers to the elements of the vector can be invalid.

You should at first reserve enough memory for the vector preventing the reallocation.

edge_vec2.reserve( SomeMaxValue );

How to link pointer to a std::vector element

You can use a std::list instead, which has the sometimes-useful property that iterators and pointers to values contained within are not invalidated upon insertion or deletion of other elements.

If you want integer indexing, use std::map<int, int> instead. Like std::list it is a node-based container which does not invalidate iterators or pointers upon insertion or deletion of other elements. You can emulate vector::push_back() like this:

void push_back(std::map<int, int>& to, int value) {
int index = to.empty() ? 0 : ((--to.end())->first + 1);
to.emplace(index, value);
}

Passing pointer on vector's elements into map

If you want pointers, you'd have to take the address of your dereferenced iterators

s = &(*x);
sport = &(*y);

I would warn you, however, that this is a fragile design if you mutate your vectors allSportsmen or allSports (e.g. push_back, emplace_back, resize, etc) that causes a reallocation, you'll likely invalidate your pointers.

Also note that you'd have to change the type of your map to store pointers

map<Sportsman*, vector<Sport*>> participants;


Related Topics



Leave a reply



Submit