Is it guaranteed by the standard that std::string
will not give back allocated memory spontaneously if reassigned from a string of a smaller size?
In other words:
std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?
I ask because i'm depending on this to avoid heap fragmentation.
Inside every std::string is a dynamically allocated array of char .
While std::string has the size of 24 bytes, it allows strings up to 22 bytes(!!) with no allocation.
The string object itself is stored on the stack but it points to memory that is on the heap. Why? The language is defined such that the string object is stored on the stack. string's implementation to construct an object uses memory on the heap.
@user1145902: They are stored in memory like in an array, but that memory is not allocated in the stack (or wherever the string object is), but rather in a dynamically allocated buffer.
[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
, andrend
.
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.
CPP reference states that assignment to a pointer-to-char
Replaces the contents with those of null-terminated character string pointed to by s as if by *this = basic_string(s), which involves a call to Traits::length(s).
This "as if" actually boils down to an rvalue assignment, so the following scenario is quite possible:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With