Thursday 28 November 2019

c++ - Is it safe to store a pointer to an item in an std::set?





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

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...