Storage of iterators inside containers

I am creating a DLL that will use another application. I want to save the current state of some data around the world in DLL memory before returning from a function call so that I can reuse the state the next time the function is called.

To do this, I need to save several iterators. I use std :: stack to store all the other data, but I was not sure if I could do this using iterators.

Is it safe to place list iterators inside container classes? If not, can you suggest a way to keep the pointer to the item in the list so I can use it later?

I know that using a vector to store my data instead of a list would allow me to save the index and reuse it very easily, but unfortunately I only need to use std :: list.

+4
source share
7 answers

Yes, everything will be fine.

Since so many other answers are devoted to the fact that this is a special quality of the list iterators, I must indicate that it will work with any iterators, including vector ones. The fact that vector iterators become invalid if the vector is modified is hardly relevant to the question of whether it is legal to store iterators in another container - this is so. Of course, an iterator can become invalid if you do everything to invalidate it, but it has nothing to do with whether the iterator is stored on the stack (or any other data structure).

+5
source

The iterators for the list are invalid only if the list is destroyed or the "pointed" element is removed from the list.

+6
source

There is no need to store iterators, just make sure that you do not use them in a copy of the list - the iterator is bound to one copy of the list and cannot be used for copying.

That is, if you do this:

std::list<int>::iterator it = myList.begin (); std::list<int> c = myList; c.insert (it, ...); // Error 

As others have noted: Of course, you also should not invalidate the iterator by deleting the element with the pointer.

+5
source

It may be offtopic, but just a hint ...

Remember that your function (s) / data structure is likely to be unsafe for read operations. There is a certain basic thread safety where read operations do not require synchronization. If you are going to store information about how much the reader is reading from your structure, this will make the entire conceptual stream unsafe and a little unnatural to use. Because no one assumes that reading is done in full.

If two threads call it, they will either have to synchronize calls, or your data structure may be in a race state. The problem with this design is that both threads must have access to a common synchronization variable.

I would suggest making two overloaded functions. Both are stateless, but one of them should take a hint iterator where to start the next search / search / search, etc. This, for example, is how Allocator is implemented in STL. You can pass a hint pointer to the allocator (default is 0) to quickly find a new piece of memory.

Yours faithfully,
Hovhannes

+2
source

Saving an iterator for a list should be great. It will not be invalidated unless you remove the same item from the list for which you saved the iterator. The following quote from the SGI site:

Lists have an important property that insertion and splicing do not invalidate iterators for enumerating elements, and that even deleting is invalid only iterators pointing to elements deleted

However, note that the previous and next element of the stored iterator may change. But the iterator itself will remain valid.

+1
source

The same rule applies to an iterator stored in a local variable, as in a more durable data structure: it will remain valid as long as the container permits.

For a list, this means: as long as the node object indicates that it is not being deleted, the iterator remains valid. Obviously, node is deleted when the list is destroyed ...

0
source

Yes. The list is the way to go. You can send my answer to a similar question here: What is the life expectancy and validity of C ++ iterators:

-1
source

All Articles