直接写入std :: strings缓冲区是否安全?

时间:2014-01-14 09:59:35

标签: c++11 stdstring

如果我有以下代码:

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

然后写入internalBuffer到hello.length()是否安全?或者这个UB /实施是否定义了?显然我可以编写测试并看到它有效,但它没有回答我的问题。

3 个答案:

答案 0 :(得分:2)

是的,这很安全。不,标准没有明确允许。
根据我半年前的标准草案副本,他们确实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()].

从这一点可以得出结论,operator []返回对该连续数组中某个位置的引用。它们还允许修改(非const)运算符[]的返回引用。
对数组的一个成员有一个非const引用我敢说我们可以修改整个数组。

答案 1 :(得分:0)

标准中的相关部分是§21.4.5:

  

const_reference operator[](size_type pos) const noexcept;

     

reference operator[](size_type pos) noexcept;

     

[...]

     

如果*(begin() + pos),则返回pos < size(),否则返回引用   T类型的对象,其值为charT(); 不得修改参考值

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

Cppreference使用的措辞略有不同:

  

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

我读到这样的''这个字符'在这里只引用默认构造的CharT,而不引用在另一种情况下返回的引用。但我承认这里的措辞有点令人困惑。

答案 2 :(得分:0)

在实践中,它是安全的,理论上 - 没有。

C ++标准不强制将string实现为顺序字符数组,就像它对vector一样。我不知道string在哪些地方不安全,但从理论上讲并不保证。

http://herbsutter.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/