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_string
和 tst_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
。
不用说,除了标准库的这个特定实现之外,您不应该依赖于此。这是一个内部细节,可能随时更改。
我有一个简单的问题。我想知道在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_string
和 tst_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
。
不用说,除了标准库的这个特定实现之外,您不应该依赖于此。这是一个内部细节,可能随时更改。