使用std :: vector,为什么&vec [0]未定义行为,但vec.data()安全吗?

Zeb*_*ish 25 c++ arrays vector undefined-behavior c++11

我一直在isocpp.org通过阅读FAQ在"链接到此处",并在整个谨慎传来,有std::vector:

std::vector<int> v;
auto a = &v[0]; // Is undefined behaviour but
auto a = v.data(); // Is safe
Run Code Online (Sandbox Code Playgroud)

从实际网站:

void g()
{
  std::vector<Foo> v;
  // ...
  f(v.begin(), v.size());  // Error, not guaranteed to be the same as &v[0]
    ????????? // Cough, choke, gag; use v.data() instead
}
Run Code Online (Sandbox Code Playgroud)

此外,&v[0]如果std::vectorstd::array为空,则使用未定义的行为,而使用该.data() 函数始终是安全的.

我不确定我是否完全理解这一点.::data()返回指向数组开头的指针,并&[0]返回开头的地址.我没有看到这里的区别,我不认为这&[0]是解除引用任何东西(即,不读取元素0处的内存).在Visual Studio中调试构建访问下标[0]导致断言失败,但在发布模式下它没有说什么.此外,两种情况下的地址对于默认构造矢量都是0.

另外我不明白关于::begin()不保证是相同的评论::operator[0].我假设对于向量,begin()迭代器中的原始指针::data(),并且&[0]都是相同的值.

son*_*yao 30

我没有看到这里的区别

&v[0]与...相同&(v[0]),即获取第一个元素的地址v.但是当它v是空的时候根本就没有元素,v[0]只是通向UB,它试图返回一个不存在的元素; 试图从中获取地址没有意义.

v.data()永远是安全的.它将直接返回指向底层数组的指针.当v为空时,指针仍然有效(它可能是空指针或不是); 但请注意,取消引用它(如*v.data())也会导致UB,与之相同v[0].

另外我不明白关于::begin()不保证是相同的评论::operator[0]

std::vector::begin将返回一个类型的迭代器std::vector::iterator,它必须满足RandomAccessIterator的要求.它可能是一个原始指针,但它不一定是.将它作为一个类实现是可以接受的.

  • @Zebrafish是`运算符&`确实返回地址,问题是它试图返回一个不存在元素的地址. (6认同)