std::string 是否总是需要堆内存?

Does a std::string always require heap memory?

我有一个简单的问题。我想知道在C++中是否std::string每次都分配内存

在我的代码中,构造函数似乎将使用比 tst_second_string 更多的内存来构造 tst_first_string:

 char* first_string = new char[5];
 strcpy(first_string, "test");
 std::string tst_first_string(first_string);
 std::string tst_second_string("test");

tst_first_stringtst_second_string 都将使用 const char* 的构造函数来构造。由于字符数 before nul-terminator 在这两种情况下是相同的,你会 想象 结构将完全相同。也就是说,C++ 标准故意对内存管理方面必须发生的事情含糊其词,因此您不会绝对确定地知道。

另请注意,许多 std::string 实现利用 短字符串优化 技术来处理小字符串,这会导致将整个对象写入具有自动存储持续时间的内存中。在您的情况下,可能根本不会使用动态内存。

我们确实知道的是,从 C++11 开始,不再允许 std::string 的写时复制语义,因此两个不同的字符串 被创建。

这取决于字符串的实现和长度。

大多数主要实现都有短字符串优化 (SSO),其中字符串存储在字符串对象本身中。

字符串文字是只读的。所以一个可能的优化是,当 std::string 指向一个文字时,它只包含一个 char * 加上一个标志,表明这就是它所代表的内容。当你写入它时,它当然必须分配内存。

这是实现定义的,但作为示例,如果字符串的长度小于 16 个字节,Visual C++ 2015 Update 3 上的 std::basic_string 实现将使用内部数组。这是来自 <xstring>_String_val 的经过大量编辑的部分:

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_SIZE 时使用 _Buf,否则使用 _Ptr

不用说,除了标准库的这个特定实现之外,您不应该依赖于此。这是一个内部细节,可能随时更改。