c++ - `std::basic_string::operator[]` 能否返回一个 "distant"保护页 nul 终止符?

标签 c++ language-lawyer c++14 stdstring c++17

所以,operator[]没有直接说s[s.size()]必须是s[s.size()-1]之后的字符在内存中。它的措辞似乎是为了避免做出这种说法。

但是s.data()指出s.data()+k == &s[k] , 和 s.data()必须返回一个指针。

忽略使用 & 的看似标准的缺陷在 CharT以上而不是std::addressof , 是否可以自由返回不同的 CharT (比如,一个在 protected 页面上,或在 ROM 中)对于 s[s.size()]在第一次调用 s.data() 之前? (很明显,它可以将缓冲区安排在一个只读页面上,上面有一个零;我说的是另一种情况)

明确地说:

据我所知,如果s.data()永远不会被调用(编译器可以证明),那么 s[s.size()]不需要与缓冲区的其余部分连续。

可以std::addressof(s[s.size()]) 在调用 s.data() 后更改并且实现符合标准(只要 s.data()+k == &s[k].data() 之前评估了 [],但编译器可以自由执行)。或者是否存在我看不到的不变性要求?

最佳答案

自 C++11 起,要求 std::string 存储在连续的内存中。这是 C++11 标准(第 24.4.1.4 节)中的引述:

The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s , the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size() .

有关 operator[] 的返回值的引述表明它返回与 &*(s.begin()+n) 相同的值(第 21.4.5.1 节):

*(begin() + pos) if pos < size() . Otherwise, returns a reference to an object of type charT with value charT() , where modifying the object leads to undefined behavior

然后我们在(第 24.4.7.1 节)中对 data() 的返回值引用了这段话:

A pointer p such that p + i == &operator[](i) for each i in [0,size()] .

所以返回的数据与使用 &operator[] 得到的一样。使用 & 运算符检索的任何值都应连续存储。所以你可以得出结论,两者都返回一个指向连续内存的指针。所以它不会返回指向距离页面的指针。

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

关于c++ - `std::basic_string::operator[]` 能否返回一个 "distant"保护页 nul 终止符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34163580/

相关文章:

c++ - 为什么 `std::reference_wrapper` 秒内不能推导出模板实例?

c++ - 这是封装集合的好(正确)方法吗?

C++ 可能的内存泄漏读取文件

c++ - C++程序中随机调用函数

c++ - 静态成员初始化期间访问私有(private)静态函数

c++ - 将 std::async 与需要函数和参数参数的函数一起使用

c - 变量赋值是语句还是表达式?

java - 什么使 "interface name"与 "class name"不同?

c++ - 如何正确实现 C++ 类析构函数

c++ - 基于 C++ 中的 bool vector 选择 vector 中的对象