3

Is it possible to store a pointer to an element inside of an std::set?

For instance take the following unsafe example...

std::vector<int> 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<std::string> 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?

chasep255
  • 11,745
  • 8
  • 58
  • 115
  • `makeString` looks OK to me. `std::unordered_set` should work just as well. – Igor Tandetnik Dec 24 '16 at 15:12
  • The main issue you're likely to encounter is an unresolved pointer should the string in the set ever be deleted. I suggest you look for a different approach unless you're prepared to take on all of the additional bookkeeping needed to make sure the code is safe or ensure no element of the set can be removed. – andand Dec 24 '16 at 15:16
  • @andand That additional book-keeping may (depending on context) be trivial. – Martin Bonner supports Monica Dec 24 '16 at 17:02
  • I don't think any of the string will be deleted once they enter the set. – chasep255 Dec 24 '16 at 18:25

1 Answers1

5

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.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64