Reputation: 1091
I have a simple question. I want to know whether std::string
allocates memory every time in C++.
In my code, it seems that the constructor will use more memory to construct tst_first_string
than for tst_second_string
:
char* first_string = new char[5];
strcpy(first_string, "test");
std::string tst_first_string(first_string);
std::string tst_second_string("test");
Upvotes: 26
Views: 9127
Reputation: 6404
String literals are read-only. So a likely optimisation is that when a std::string
points to a literal it consists merely of a char *
plus a flag to say this is what it represents. When you write to it of course it will have to allocate memory.
Upvotes: -4
Reputation: 234875
Both tst_first_string
and tst_second_string
will be constructed using the constructor to const char*
. Since the number of characters before the nul-terminator is the same in both cases, you'd imagine that the construction will be exactly identical. That said the C++ standard is intentionally vague as to what must happen with regards to memory management so you will not know with absolute certainty.
Note also that many std::string
implementations exploit a short string optimisation technique for small strings which causes the entire object to be written to memory with automatic storage duration. In your case, dynamic memory may not be used at all.
What we do know for certain is that from C++11 onwards, copy on write semantics for std::string
is no longer permitted, so two distinct strings will be created.
Upvotes: 22
Reputation:
This is implementation-defined, but as an example, the std::basic_string
implementation on Visual C++ 2015 Update 3 will use an internal array if the length of the string is less than 16 bytes. Here's a heavily edited portion of _String_val
from <xstring>
:
template<class _Val_types>
class _String_val
{
public:
typedef typename _Val_types::value_type value_type;
enum
{ // length of internal buffer, [1, 16]
_BUF_SIZE = 16 / sizeof (value_type) < 1 ? 1
: 16 / sizeof (value_type)
};
value_type *_Myptr()
{ // determine current pointer to buffer for mutable string
return (this->_BUF_SIZE <= _Myres
? _Bx._Ptr
: _Bx._Buf);
}
union _Bxty
{ // storage for small buffer or pointer to larger one
value_type _Buf[_BUF_SIZE];
pointer _Ptr;
} _Bx;
};
If you look at _Myptr()
, you'll notice _Buf
is used when the length is less than _BUF_SIZE
and _Ptr
is used otherwise.
Needless to say, you shouldn't rely on this being true for anything else than this particular implementation of the standard library. It is an internal detail that may change at any time.
Upvotes: 2
Reputation: 1036
It depends on the implementation and length of the string.
Most major implementations have short string optimization (SSO), where the string is stored in the string object itself.
Upvotes: 13