如果vec.size()== 0,vec.data()会返回什么?

Sza*_*lcs 27 c++ vector

cppreference有这样的说明std::vector::data:

返回指向用作元素存储的基础数组的指针.指针使得范围[data(); data() + size()) 始终是有效范围,即使容器为空.

"有效范围"到底意味着什么?data()如果向量是零长度会返回什么?

具体来说,对于零长度矢量:

  1. 可以data()成为空指针吗?
  2. 可以安全地解除引用吗?(即使它指向垃圾.)
  3. 是否保证两个不同(零长度)矢量之间的差异?

我正在使用一个带有数组的C库,即使对于零长度数组也不允许空指针.但是,如果数组长度为零,它实际上不会取消引用数组存储指针,它只检查它是否为NULL.我想确保我可以安全地传递data()给这个C库,所以唯一相关的问题是上面的(1).(2)和(3)只是出于好奇而出现类似情况.


更新

根据未转化为答案的评论,我们可以尝试以下程序:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v;
    cout << v.data() << endl;

    v.push_back(1);
    cout << v.data() << endl;

    v.pop_back();
    cout << v.data() << endl;

    v.shrink_to_fit();
    cout << v.data() << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用我的编译器输出:

0x0
0x7f896b403300
0x7f896b403300
0x0
Run Code Online (Sandbox Code Playgroud)

这表明:

  • data() 确实可以是空指针,因此答案是(1)是(2)否(3)否

  • 但它并不总是零大小向量的空指针

是的,显然我应该在问之前尝试过这个.

M.M*_*M.M 21

"有效范围"由[iterator.requirements.general]/7(C++ 14)定义:

" [i,j)当且仅当j可以从i" 到达时,范围才有效.

幸运的是,C++定义了添加0空指针会产生空指针.那么,是否可以从空指针到达空指针?这由同一部分的第6点定义:

迭代器j被称为到达从一个迭代i,当且仅当存在的表达的应用程序的有限序列++i,使i == j.

零长度序列是有限序列,因此data()可以返回空指针.

因此,您的问题的答案是:

  1. 可以data()成为空指针吗?

  1. 可以安全地解除引用吗?(即使它指向垃圾.)

没有

  1. 是否保证两个不同(零长度)矢量之间的差异?

没有

  • @Szabolcs:不,指针不是偶数.从你不能添加两个指针的事实可以看出这一点.至于非负数,因为它们不是数字,它们不能与数字进行比较,所以`ptr <0`也没有意义,它们既没有签名也没有签名. (7认同)

Cap*_*ffe 6

评论太长,所以发帖在这里.

我期望迭代器对于空序列是nullptr所以我测试了它.

#include <iostream>
#include <vector>

void pr(std::vector<int>& v){
    std::cout << &*v.begin() << ", " << &*v.end() << "\n";
} 
// technically UB, but for this experiment I don't feel too bad about it.
// Thanks @Revolver    
int main(int argc, char** argv) {
    std::vector<int> v1;
    std::vector<int> v2;

    pr(v1);
    pr(v2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这确实打印出来了

0, 0
0, 0 
Run Code Online (Sandbox Code Playgroud)

现在对于一个空容器,有效范围的唯一合理操作是begin() == end().不,垃圾不能被解除引用所以*v.begin()不是一个问题.

  • 此代码包含未定义的行为(取消引用无效的迭代器).无论如何:http://coliru.stacked-crooked.com/a/7ebaf9f496bbfb21 (6认同)
  • @Szabolcs另一个更接近原始答案的反驳:http://coliru.stacked-crooked.com/a/2ce8a1a2eeeed071只有当vector __always__为空时才会得到空指针 (3认同)
  • 这不能回答向量的作用.它回答了编译器在此特定实例中所做的事情. (2认同)

Pau*_*ans 5

从标准:

23.3.6.4 [vector.data]

T*data()noexcept;

const T*data()const noexcept;

返回:指针使得[data(),data()+ size())是有效范围.对于非空向量,data()==&front().

因此,对于空向量,它允许为null,但不一定是dereferencable也不是唯一的.

  • 你的引言的哪一部分支持断言`data`被允许为空矢量的'null`? (2认同)