为了账号安全,请及时绑定邮箱和手机立即绑定

在C ++ 11中string :: c_str()不再为null终止吗?

在C ++ 11中string :: c_str()不再为null终止吗?

C++
开心每一天1111 2019-12-03 15:07:07
在C ++ 11中,basic_string::c_str它定义为与完全相同basic_string::data,而后者又定义为*(begin() + n)与和*(&*begin() + n)(when 0 <= n < size())完全相同。我找不到任何要求字符串末尾始终包含空字符的内容。这是否意味着c_str()不再保证生成以null终止的字符串?
查看完整描述

3 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

现在需要字符串才能在内部使用以空值结尾的缓冲区。看一下operator[](21.4.5)的定义:


要求: pos <= size()。


返回: *(begin() + pos)如果pos <

  size(),否则返回对T带有value 类型的对象的引用charT();参考值不得修改。


回顾c_str(21.4.7.1/1),我们看到它的定义是operator[]:


返回:指针,p这样in 中p + i == &operator[](i)的每个指针。i[0,size()]


并且c_str和data都必须为O(1),因此有效地强制实现使用以空值结尾的缓冲区。


此外,正如DavidRodríguez-dribeas在评论中指出的那样,返回值要求还意味着您可以&operator[](0)用作的同义词c_str(),因此终止的空字符必须位于相同的缓冲区中(因为*(p + size())必须等于charT());这也意味着即使终止符被延迟初始化,也无法观察中间状态的缓冲区。


查看完整回答
反对 回复 2019-12-03
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

“历史”是很久以前,当每个人都在单个线程中工作,或者至少线程是拥有自己数据的工人时,他们为C ++设计了一个字符串类,该类使字符串处理比以前更容易,并且它们重载了运算符+连接字符串。


问题是用户将执行以下操作:


s = s1 + s2 + s3 + s4;

并且每个串联都会创建一个临时对象,该临时对象必须实现一个字符串。


因此,有人会产生“惰性评估”的头脑,以便在内部可以将所有字符串存储在某种“绳子”中,直到有人想要将其读取为C字符串为止,此时您可以将内部表示形式更改为连续的缓冲区。


这解决了上述问题,但引起了其他麻烦,特别是在多线程世界中,人们期望.c_str()操作为只读/不会更改任何内容,因此不需要锁定任何内容。在类实现中过早地进行内部锁定,以防万一有人对它进行多线程处理(甚至在没有线程标准的情况下)也不是一个好主意。实际上,做任何事情都比每次简单地复制缓冲区要昂贵得多。字符串实现放弃了“写时复制”实现的相同原因。


因此,做.c_str()一个真正不变的操作被认为是最明智的选择,但是现在可以“依赖”线程感知的标准吗?因此,新标准决定明确声明您可以,因此内部表示形式必须包含空终止符。


查看完整回答
反对 回复 2019-12-03
  • 3 回答
  • 0 关注
  • 833 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信