我今天和我的同事想知道是否可以实现std :: vector来利用小缓冲区优化。通过查看C ++ 11草案,我在23.3.1p8阅读
表达式a.swap(b),对于除数组之外的标准容器类型的容器a和b,应交换a和b的值,而不调用单个容器元素上的任何移动,复制或交换操作。
起初似乎禁止小缓冲区优化,但在as-if规则下,我们将被允许仍然对非类型类型进行小缓冲区优化(因为我们无法观察到正在完成的复制)。下一个文字似乎更难“傻瓜”
在交换之前引用一个容器中的元素的每个迭代器应该在交换之后引用另一个容器中的相同元素。
这是否足以阻止为std :: vector实现小缓冲区优化?是否有其他路障或最终是否可能有一个带SBO的std :: vector?
答案 0 :(得分:46)
23.2.1 / p10 / b6:
除非另有说明......
- 没有swap()函数使引用被交换容器元素的任何引用,指针或迭代器无效。 ...
vector
无处“另外指定”。因此,这将取消了vector
的SBO。
string
不受此规则的约束,因为它在21.4.1 / p6中“另有说明”:
引用a的元素的引用,指针和迭代器 basic_string序列可能会被以下用途无效 basic_string对象:
- 作为任何标准库函数的参数,将非const basic_string作为参数引用。^ 234
234)例如,作为非成员函数的参数swap() (21.4.8.8),运算符>>()(21.4.8.9)和getline()(21.4.8.9),或者as basic_string :: swap()
的参数
答案 1 :(得分:1)
除了迭代器失效的问题之外,还有一个安全参数可以避免小缓冲区优化。
如果写入超出std::vector
,则会出现堆损坏,这很难预测会被覆盖的内容,并且很难用于任意代码执行。
如果缓冲区嵌入在局部变量中,则溢出会破坏堆栈,攻击者可能会控制返回地址,这样更有用(例如,返回libc攻击)。