C++11 直接写入std::strings缓冲区安全吗?

C++11 直接写入std::strings缓冲区安全吗?,c++11,stdstring,C++11,Stdstring,如果我有以下代码: std::string hello = "hello world"; char* internalBuffer = &hello[0]; 那么,在hello.length()之前写入internalBuffer是否安全?或者该UB/实现是否已定义?显然,我可以编写测试,并看到这是可行的,但它不能回答我的问题。标准中的相关章节是§21.4.5: const_参考运算符[](size_type pos)const noexcept reference操作符[](siz

如果我有以下代码:

std::string hello = "hello world"; 
char* internalBuffer = &hello[0];

那么,在hello.length()之前写入internalBuffer是否安全?或者该UB/实现是否已定义?显然,我可以编写测试,并看到这是可行的,但它不能回答我的问题。

标准中的相关章节是§21.4.5:

const_参考运算符[](size_type pos)const noexcept

reference操作符[](size_type pos)无异常

[……]

返回:
*(begin()+pos)
如果
pos
,则返回对 类型为
T
的对象,值为
charT()
不得修改参考值

如果我理解正确,这意味着只要给
操作符[]
的索引小于字符串的
大小,就可以修改该值。但是,如果索引等于
size
,因此我们获得了终止字符串的
\0
,我们就不能写入该值

此处使用稍微不同的措辞:

如果pos==size(),则返回对值为
CharT()
(空字符)的字符的引用。 对于第一个(非常量)版本,如果修改此字符,则行为未定义


我阅读此内容时,这里的“此字符”仅指默认构造的
图表
,而不是指在另一种情况下返回的引用。但我承认这里的措辞有点混乱。

实际上,理论上它是安全的——不

C++标准并不强制将
字符串
实现为序列字符数组,就像它对
向量
所做的那样。我不知道有任何
string
的实现是不安全的,但理论上没有保证


是的,很安全。不,这不是标准明确允许的
根据我半年前的标准草案副本,他们确实确保
data()
指向一个连续的数组,并且该数组与您从操作符[]收到的数组相同:

21.4.7.1 basic_string accessors [string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
由此可以得出结论,运算符[]返回对该连续数组中某个位置的引用。它们还允许修改从(非常量)运算符[]返回的引用

对于数组中的一个成员有一个非常量引用,我敢说我们可以修改整个数组。

因为
str[I]='c'
定义得很好,所以我希望您的示例也定义得很好。我很好奇答案可能是什么。可能是@axe的副本而不是副本,因为这种行为是用C++11更改的。哦,可能是在最新的标准中更改的。需要检查。AFAIK是的,它发生了变化,这是因为它在不同的库中都是这样实现的。这样一个短语通常适用于整个“
*(begin()+pos)
如果
pos
,否则是对
T
类型的对象的引用,其值
charT()
”,但这在这里没有任何意义……这就是为什么在以后的草案()中对文本进行了更改。