c++ - 默认构造的 std::string c_str() 值

标签 c++ stdstring

std::string s1;
std::string s2;
assert(strlen(s1.c_str()) == 0);
assert(s1.c_str() == s2.c_str());

这两个断言总是为真吗?

我使用的是 C++11,我已经检查了标准,§21.4.2 中的表 63 说:

data() a non-null pointer that is copyable and can have 0 added to it

size() 0

capacity() an unspecified value

我认为c_str()data()是一样的。但是我对这个定义有一些疑问。

  1. 可以是否添加了 0”==“必须且总是添加了 0”?

  2. 是否所有默认构造的 std::string 共享同一个底层缓冲区?

我在gcc上测试,这两个断言是真的。我想知道这些是否对所有编译器都适用?

最佳答案

第一个断言保证成功。 c_str() 总是返回一个指向以 null 结尾的字符串的指针,该字符串的内容与 std::string 对象所持有的内容相同,该对象对于 s1

第二个断言不保证成功。如果内容相同,则无需从 std::string 返回的 c_str() 相同。默认构造的字符串不需要共享相同的底层缓冲区。那将是特定标准库实现的实现细节。 (我认为 libstdc++ 会根据某些向后兼容性(?)原因的配置做类似的事情,如果我没记错的话,请参阅 --enable-fully-dynamic-string configure 选项)。

请注意,在 C++11 之前,data() 具有与 c_str() 相同的效果。 data() 不能保证提供指向以 null 结尾的字符串的指针。如果字符串为空,则不允许取消引用它返回的指针。因此,在 C++11 之前,将示例中的 c_str() 替换为 data() 会导致调用 strlen 时出现未定义的行为>.


and can have 0 added to it”的措辞有点奇怪,我不完全确定它应该传达什么,但对于 C++11(草案 N3337) data() 的返回值在 [string.accessors]/1 中进一步指定因此 data() + i == &operator[](i) 对于 [0,size()] 范围内的所有 ioperator[][strings.access]/2 中指定无条件地为 operator[](size()) 返回对 CharT()(又名空字符)的引用。

奇怪的措辞也已通过 2018 年的编辑更改被替换,请参阅 https://github.com/cplusplus/draft/pull/1879 .

关于c++ - 默认构造的 std::string c_str() 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72654693/

相关文章:

C++指针练习

c++ - WinApi:无法读取注册表

c++ - C/C++ 套接字 : IPv6 TCP connection fails if I do anything before it

如果我不使用 Code::Blocks 但使用 cygwin 进行编译,c++ compare std::string 将不起作用

c++ - 空终止字符串,它真的是由标准规定的吗?

c++ - 从标准 :string to add typedefs and enums 派生

C++ 如何将成员函数传递给仿函数参数?

c++ - 与零比较时的 int 运算符 != 和 ==

c++ - 为什么 std::string 没有标准定义的文字后缀?

c++ - “null-terminated transparent array of elements”中的transparent是什么意思