如果我有以下代码:
std::string hello = "hello world";
char* internalBuffer = &hello[0];
然后写入internalBuffer到hello.length()是否安全?或者这个UB /实施是否定义了?显然我可以编写测试并看到它有效,但它没有回答我的问题。
答案 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/