C访问向量超出size()且低于Capacity()

C++ access vector beyond size() and under capacity()

在索引i之外和向量capacity()下的索引i中访问向量data()[i]是否安全?

这是我的理由:

a)根据cplusplus,capacity()是"当前为向量分配的存储空间的大小",这使我认为问题的答案是YES,但是

b)使用reserve()并访问vector size()之外的data应该是安全的,因为根据cplusplus的说法,reserve()"导致容器重新分配其存储,从而将其容量增加到n",但是然后

c)Stackoverflow主题与上面的b)语句

相矛盾

所以我很困惑,正在寻找答案。


如果n >= size(),则访问data()[n]无效。每个[vector.data] std::vector::data

Returns: A pointer such that [data(), data() + size()) is a valid range. For a non-empty vector, data() == addressof(front()).

因此,仅使用[0, size())范围内的值访问data是有效的。

通常,data() + size() - 1data + capacity()之间的内存未初始化。如果您从该未初始化的内存中读取,则为未定义的行为。如果您的对象具有非平凡的初始化,那么您甚至无法为其分配值,因为该位置实际上没有对象,仅一个空间就可以了。您可能会在未初始化的范围内执行操作,但是您违反了std::vector的合同,如果您这样做,可能会很生气;)


不,这是不安全的,因为ISO / IEC 14882:2014的§23.3.6.4规定了

vector data ... Returns: A pointer such that [data(),data() + size()) is a valid range.

因此,按照标准,size()以外的所有内容均未定义,这意味着每个人都会确认的所谓未定义行为是非常不安全的。

说句公道话,通常不会发生任何不好的情况,但这通常是非常弱的,这意味着会发生另一种编译器,操作系统和繁荣时期,您无法分辨。并且为了完整起见,有几种实现可能会崩溃的实现,例如,当您使用地址清理进行编译时,我认为。只是不要这样做。