Is it possible to store a pointer to an element inside of an std::set?
For instance take the following unsafe example...
std::vector vec;
//add a bunch of items
int* ptr = &vec[10];
//add more items
std::cout << *ptr << std::endl;
In this case the memory which ptr points to could have been invalidated by adding extra elements to the vector causing it to reallocate. However if I had used a linked list instead of a vector I believe this would have been safe since it does not need to reallocate the nodes.
I want to use an std::set to save memory when dealing with redundant strings. Would the following example be safe? I think it would be for std::set but not for std::unordered_set.
const char* makeString(const char* s)
{
static std::set strings_pool;
return strings_pool.insert(s).first->c_str();
}
If the string c is not already in the strings_pool it is inserted otherwise it returns an iterator to the string already in the pool. In either case I get the value of the iterator and return the pointer to underlying cstring. I think that this is a safe operation but can someone confirm it.
At this link http://en.cppreference.com/w/cpp/container/set/insert it says "No iterators or references are invalidated." I think this means I can do it.
Also under the documentation for std::unordered_set it says "References are not invalidated." Does this means it is safe to use std::unordered_set as well?
Answer
Yes, both set
and unordered_set
are safe in this regard. If references are not invalidated, your pointers also remain valid.
It's an easy property for the node-based collections to maintain; unlike vector
there's no need for them to move values around in memory.
No comments:
Post a Comment