访问向量data()[i]
之外的索引i
和向量size()
下的索引capacity()
是否安全?
这是我的理由:
a)根据cplusplus,capacity()
是“当前为向量分配的存储空间的大小”,这使我认为问题的答案是YES
,但是然后
b)使用reserve()
并访问向量data
之外的size()
应该是安全的,因为根据cplusplus,reserve()
“使容器重新分配其存储空间将其容量增加到n”,但随后
c)Stackoverflow topic与上面的声明b)
矛盾
所以我很困惑,正在寻找答案。
答案 0 :(得分:6)
如果data()[n]
,则访问n >= size()
是无效的。每个[vector.data] std::vector::data
返回:诸如
[data(), data() + size())
是有效范围的指针。对于非空向量,请data() == addressof(front())
。
因此,仅使用data
范围内的值访问[0, size())
。
通常,data() + size() - 1
和data + capacity()
之间的内存未初始化。如果您从该未初始化的内存中读取,则为未定义的行为。如果您的对象具有非平凡的初始化,那么您甚至无法为其分配值,因为在该位置实际上没有对象,而只有一个空间。您可能可以在未初始化的范围内进行操作,但是您违反与std::vector
的合同,并且如果这样做会很生气;)
答案 1 :(得分:3)
不,这不是不安全,因为ISO / IEC 14882:2014的§23.3.6.4规定了
矢量数据...返回:一个指针,使得[data(),data()+ size())是有效范围。
因此,按照标准,size()
以外的所有内容均未定义,这意味着所谓的未定义行为(每个人都会确认)是非常不安全的。
说句公道话,通常不会发生任何不好的情况,但这通常是非常弱的,这意味着会发生另一种编译器,操作系统和繁荣时期,您无法分辨。并且为了完整起见,有几种实现可能会崩溃,例如,当您使用地址清理进行编译时,我认为。只是不要这样做。