Подтвердить что ты не робот

Требуется ли std::string кучная память?

У меня есть простой вопрос. Я хочу знать, выделяет ли std::string память каждый раз в С++.

В моем коде кажется, что конструктор будет использовать больше памяти для построения tst_first_string, чем для 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");
4b9b3361

Ответ 1

Оба tst_first_string и tst_second_string будут построены с использованием конструктора до const char*. Поскольку число символов до nul-terminator одинаково в обоих случаях, вы можете себе представить, что конструкция будет точно идентичной. Тем не менее, стандарт С++ намеренно неопределенен относительно того, что должно произойти в отношении управления памятью, чтобы вы не знали с абсолютной уверенностью.

Обратите также внимание на то, что многие реализации std::string используют метод оптимизации коротких строк для небольших строк, что заставляет весь объект записываться в память с автоматическим временем хранения. В вашем случае динамическая память может вообще не использоваться.

То, что мы знаем наверняка, это то, что начиная с С++ 11 копирование на семантику записи для std::string больше не разрешено, поэтому будут созданы две различные строки.

Ответ 2

Это зависит от реализации и длины строки.

Большинство основных реализаций имеют короткую оптимизацию строк (SSO), где строка хранится в самом объекте строки.

Ответ 3

Это реализация, но в качестве примера реализация std::basic_string в Visual С++ 2015 Update 3 будет использовать внутренний массив, если длина строки меньше 16 байт. Здесь сильно отредактированная часть _String_val из <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;
};

Если вы посмотрите _Myptr(), вы заметите, что _Buf используется, когда длина меньше _BUF_SIZE и _Ptr используется иначе.

Излишне говорить, что вы не должны полагаться на то, что это верно для всего, кроме этой конкретной реализации стандартной библиотеки. Это внутренняя деталь, которая может измениться в любое время.

Ответ 4

Строковые литералы доступны только для чтения. Поэтому вероятная оптимизация заключается в том, что когда std::string указывает на литерал, он состоит только из char * плюс флаг, чтобы сказать, что это то, что он представляет. Когда вы пишете, конечно, ему придется выделять память.