【发布时间】:2016-03-15 09:20:04
【问题描述】:
cppreference 有 std::vector::data 的注释:
返回指向作为元素存储的底层数组的指针。指针使得范围
[data(); data() + size())始终是有效范围,即使容器为空。
这里的“有效范围”到底是什么意思?如果向量长度为零,data() 会返回什么?
具体来说,对于零长度向量:
-
data()可以是空指针吗? - 可以安全地取消引用吗? (即使它指向垃圾。)
- 是否保证两个不同(零长度)向量之间存在差异?
我正在使用一个 C 库,它接受数组并且即使对于零长度数组也不允许空指针。但是,如果数组长度为零,它实际上并没有取消引用数组存储指针,它只是检查它是否为NULL。我想确保我可以安全地将data() 传递给这个 C 库,所以唯一相关的问题是上面的 (1)。 (2) 和 (3) 只是出于好奇,以防出现类似情况。
更新
根据没有转成答案的cmets,我们可以试试下面的方案:
#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;
}
用我的编译器输出:
0x0
0x7f896b403300
0x7f896b403300
0x0
这表明:
data()确实可以是空指针,因此答案是 (1) 是 (2) 否 (3) 否但它并不总是零大小向量的空指针
是的,显然我应该在询问之前尝试一下。
【问题讨论】:
-
size() == 0时,[data(); data() + size())中没有元素,所以可能没有有效的指针。 (我将其作为评论发布,因为我不确定) -
是、否和否.. 现在没有标准的链接,否则会回答的。
-
我会说返回值是未定义的,因为标准没有明确定义(例如
arraydata方法返回值被定义为未指定和begin() == end() == data()) -
@Revolver_Ocelot 如果未定义,则为缺陷。
-
@Szabolcs:实际上,“即使容器是空的”文本在您的引用中实现的所有效果,是确认
data()必须返回T*类型的值,即使向量是空的。我猜他们觉得有必要加强这一点,以防万一阅读文本的实施者认为由于没有“底层存储”用于空向量,因此用户不应该在其上调用data()。因此,因为对于任何指针值p、p + 0 == p和[p,p)都是有效范围,通过说“即使为空”,他们基本上只是在说“它仍然是一个指针”。