Oscar
Oscar

Reputation: 1091

Does a std::string always require heap memory?

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

Answers (4)

Malcolm McLean
Malcolm McLean

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

Bathsheba
Bathsheba

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

anon
anon

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

Kent
Kent

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

Related Questions