`std::basic_string::operator[]`可能返回一个远程受保护的页空终止符吗?

8
因此,operator[]并没有直接说明s[s.size()]必须是s[s.size()-1]后面的字符。看起来这样措辞是为了避免这种说法。
但是s.data()表明s.data()+k == &s[k],而且s.data()必须返回一个指针。
忽略上面在CharT上使用&而不是std::addressof似乎是标准缺陷的问题,那么实现是否可以在第一次调用s.data()之前为s[s.size()]返回一个不同的CharT(比如在受保护的页或ROM中)?(显然它可以安排缓冲区在只读页面上以及带有零的页面上结束;我谈论的是不同的情况)
明确一下:
据我所知,如果从未调用s.data()(并且编译器可以证明它),则s[s.size()]不需要与缓冲区的其余部分连续。
在调用s.data()后,std::addressof(s[s.size()])是否可以更改,并且实现是否符合标准(只要s.data()+k == &s[k][]之前评估.data(),但编译器可以强制执行)。还是有我看不到的不可变性要求?

cppreference 明确表示,自 C++11 以来 operator[] 的行为与您对 data() 描述的完全相同。但是它还提到,这个字符不能被修改。 - SergeyA
1
@SergeyA 上面的措辞是我对(当前草案)标准的理解,而不是基于其他人的(例如最后编辑cppreference的人)解释。如果您想要,我可以添加直接引用,但它们并不难找(打开您的标准,搜索basic_string,从索引跳转到它,然后从那里搜索operator[data()。我想知道是否有其他限制我错过了(就像我最初错过了对s[s.size()].data()暗示限制一样)。大多数明显的限制(基于迭代器)不适用,因为*s.end()仍然是未定义行为。 - Yakk - Adam Nevraumont
标准是否确实声明s[s.size()]是良好定义的而不是UB?毕竟,它已经超出了字符串的末尾,并且对于任何其他容器来说都将是UB。作为实际问题,每个实现可能都会保留c_str()所需的终止空值,因此这可能是一个无意义的问题。 - Mark Ransom
1
@MarkRansom 是的,它在 operator[] 的定义中有说明。它必须返回一个 CharT 引用(根据情况可以是 const 或非 const),其值等于 CharT()。修改它将导致未定义行为。正是对保护该空终止符的思考引发了上述问题。 - Yakk - Adam Nevraumont
1个回答

1
自从 C++11 开始,std::string 要求以连续内存进行存储。这是来自于 C++11 标准(第 24.4.1.4 章节)的引用:
“basic_string 对象中的 char 类型对象应该被连续地存储。也就是说,对于任何 basic_string 对象 s,当且仅当 0 <= n < s.size() 时,&*(s.begin() + n) == &*s.begin() + n 的标识符成立。”
关于 operator[] 返回值的引用,它声明了它返回值与 (section 21.4.5.1) 中的 &*(s.begin()+n) 相同:
如果 pos < size(),则为 *(begin() + pos),否则,返回一个类型为 charT 的对象的引用,其值为 charT(),修改该对象会导致未定义行为。
接下来,我们有关于 data() 返回值的引用 (section 24.4.7.1):

对于每个 i 在 [0,size()] 中,存在指针 p 使得 p + i == &operator[](i) 。

因此,data返回的结果与使用&operator[]获取的结果相同。而且你检索到的任何值都应该被存储在连续的位置上。因此,两者都返回指向连续内存的指针。所以它不会返回指向远距离页面的指针。

请注意,这仅适用于C++11。在C++11之前,标准没有做出这样的保证。


现在应该已经修复了。 - Shadowwolf
1
你的第一和第二个引用特别排除了 n == s.size()pos == size() 的情况。 - user2357112
2
@Yakk:第二个引文中支持“operator[]”返回对“*(s.begin()+n)”的引用的声明的部分不包括“n == s.size()”的情况。 - user2357112
我看不到调用[s.size()]会返回一个稳定的位置的保证。上面唯一的要求似乎是一旦你调用了data(),它必须返回一个超出结尾的指针;在此之前,我看不到任何限制。这与您的结论不符吗? - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接