Is std::string guaranteed not to give back memory spontaneously?

No guarantee whatsoever.

[string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:

[string.cons]/32

basic_string& operator=(basic_string&& str)  noexcept(/*...*/)

Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.

This shows that the Committee let the implementation choose freely between an invalidating operation and a more conservative one. And to make things even clearer:

[basic.string]/4

References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:

  • (4.1) as an argument to any standard library function taking a reference to non-const basic_­string as an argument.
  • (4.2) Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.

I ask because i’m depending on this to avoid heap fragmentation.

std::string takes as template-parameter an allocator. If you’re really concerned by a possible heap fragmentation, you could write your own, which with some heuristics could have an allocation strategy suited for your needs.

In practice, most implementations I know of would not reallocate memory in the case of your question. This can be checked by testing and/or checking your implementation doc and eventually source code.

Leave a Comment