如何获取指向std::vector原始数据的指针?

185

我试图将 std::vector 用作 char 数组。

我的函数接受一个空指针:

void process_data(const void *data);

以前我只是使用了这段代码:

char something[] = "my data here";
process_data(something);

之前的代码如预期一样运行。

但现在我需要 std::vector 的动态性,所以我尝试了以下代码:

vector<char> something;
*cut*
process_data(something);

问题是,我该如何将 char 向量传递给我的函数,以便可以访问向量的原始数据(无论其格式是什么 - 浮点数等)?

我尝试过这样:

process_data(&something);

还有这个:

process_data(&something.begin());

但它返回了一条指向乱码数据的指针,后者给出了警告:warning C4238: nonstandard extension used : class rvalue used as lvalue

3个回答

277
&something 给出了 std::vector 对象的地址,而不是其所包含数据的地址。&something.begin() 给出了 begin() 返回的迭代器的地址(编译器警告,此操作在技术上不被允许,因为 something.begin() 是一个 rvalue 表达式,所以其地址不能被获取)。
假设容器中至少有一个元素,则可以通过以下方式获取容器中最初元素的地址:
  • &something[0]&something.front() (索引值为 0 的元素的地址),或

  • &*something.begin() (由 begin() 返回的迭代器指向的元素的地址)。

在 C++11 中,std::vector 新增了一个成员函数: data()。该成员函数返回容器中初始元素的地址,与 &something.front() 类似。这个成员函数的优点是,即使容器为空,也可以调用它。

121
重要提示:请小心使用 vector<bool>,它是这个答案的一个例外(并且不具有连续的布尔值内存存储)。 - Motti
21
好的一面是,没有太多需要注意的地方:这三种方法都无法编译std::vector<bool>,因为std::vector<bool>需要使用代理对象,而该代理对象不能隐式转换为bool*。作为解决方法,如果确实需要一个bool序列,最好只使用std::vector<char>。@Motti - James McNellis
7
尽可能全面地说,但主要是针对.data() - 我会假装我没有看到那个丑陋的&*iterator :P - underscore_d
2
指针从data()返回后会存活多久? 如果永远不通过push_back()或其他函数(包括reserve)调整向量大小(更大或更小),那么它保证指针将与向量一起存活,并指向正确的位置吗? - johnbakers
请注意,在空向量上调用data()是安全的,但其结果大多无用。它将指向一些内存,即使向量中没有元素,这可能是意外的。 - André
显示剩余3条评论

95

something.data()会返回指向向量数据空间的指针。


1
error C2039: 'data' : is not a member of 'std::vector<_Ty>' - Rookie
2
@Rookie:看起来你正在使用一个有问题的编译器——C++规范中的23.3.6.3定义了vector::data。尝试向你的供应商报告错误或获取更好的编译器。 - Chris Dodd
2
@Chris Dodd 我也遇到了同样的错误。我正在使用Visual Studio 2008。 - bodacydo
38
@ChrisDodd: vector::data() 是 C++11 中新增的函数。 - HighCommander4
我使用Visual Studio 2012,他们一定添加了vector::data(),因为我经常使用它。 - Robert Snyder
我喜欢使用sth.data(),但最近不得不回滚到&sth.front()。我们的系统只支持g++34... - fchen

13

改为指向第一个元素的指针:

process_data (&something [0]);

我认为即使没有下标括号,它也会返回第一个项目的内存地址? - Tim
那是针对数组的,不是针对向量的。 - Steven Don
是的,我刚意识到了,抱歉。 - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接