`std :: basic_string :: operator []`可以返回"遥远的"受保护的页面nul终止符?

时间:2015-12-08 18:44:03

标签: 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的看似标准缺陷,是实现免费返回不同的s[s.size()](例如,一个受保护的第一次拨打s.data()之前s.data()的页面或ROM)? (显然,它可以将缓冲区安排在一个只读的页面上结束;我说的是另一种情况)

明确:

据我所知,如果永远不会调用s[s.size()](并且编译器可以证明它),则std::addressof(s[s.size()])不需要与缓冲区的其余部分连续。

s.data()调用后s.data()+k == &s[k] 可以更改,并且实施符合标准(只要.data()之前评估[] #!/usr/bin/env ruby require "yaml" def check_file(filename) YAML.parse_file(filename) puts "OK" 0 rescue Psych::SyntaxError => ex puts "Error#{ex.message[/: .+/]}" 1 end exit_code = 0 max_filename_length = ARGV.max_by(&:size).size ARGV.each do |filename| printf "%-*s ", max_filename_length, filename exit_code |= check_file(filename) end exit exit_code ,但编译器可以自由执行)。或者是否有我看不到的不可变性要求?

1 个答案:

答案 0 :(得分:1)

从C ++ 11开始,std :: string需要存储在连续的内存中。这是C ++ 11标准的引用(第24.4.1.4节):

  

一个类似char的对象   basic_string的   对象应连续存储。也就是说,对任何人来说   basic_string的   宾语   小号   , 身份   & *(s.begin()+ n)==& * s.begin()+ n   应坚持所有的价值观   ñ   这样的   0   < = n< s.size()   

关于operator []的返回值的引用声明它返回与&*(s.begin()+n)相同的内容(第21.4.5.1节):

  

*(begin()+ pos)   如果   pos<尺寸()   。否则,返回对类型对象的引用   图表   有价值的   图表()   ,修改对象导致未定义的行为

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

  

一个指针   p   这样的   p + i ==& operator [](i)   为每个人   一世   在   [0,大小()]   

因此,数据返回与使用& operator []时相同。使用&运算符检索之间的任何值都应该连续存储。所以你可以得出结论都返回指向连续内存的指针。因此它不会返回指向距离页面的指针。

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