No guarantee whatsoever.
[string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:
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:
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.
std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operatorsnewanddelete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.