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


160

我试图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

Answers:


238

&something给您std::vector对象的地址,而不是它保存的数据的地址。 &something.begin()为您提供返回的迭代器的地址begin()(如编译器警告,从技术上讲,这是不允许的,因为它something.begin()是一个右值表达式,因此无法获取其地址)。

假设容器中至少包含一个元素,则需要获取容器的初始元素的地址,您可以通过

  • &something[0]&something.front()(索引为0的元素的地址),或

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

在C ++ 11中,新的成员函数已添加到std::vector:中 data()。就像一样,该成员函数返回容器中初始元素的地址&something.front()。该成员函数的优点是,即使容器为空,也可以调用它。


103
重要提示请注意,vector<bool>此答案是一个例外(并且不具有bools 的连续内存存储)。
Motti

18
从好的方面来说,没有什么要提防的:这三种方法都无法编译,std::vector<bool>因为std::vector<bool>需要使用代理对象,并且不能将代理隐式转换为bool*。解决此问题的方法是,如果确实需要一个序列bool,则最好仅使用std::vector<char>。@Motti
James McNellis 2011年

是的,当心是一般性的,而不是直接作为您的答案,因为没有连续的内存存储,因此无法解决。
Motti

7
为全面而准备,但主要是为了.data()-我假装我没有看到丑陋的&*iterator:P
underscore_d

2
指针将返回多长时间data()?如果从不通过(通过push_back()或其他函数,包括或通过)其他函数来调整矢量的大小reserve,那么是否可以保证指针在指向矢量的正确位置上一直有效?
johnbakers 2016年

81

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


error C2039: 'data' : is not a member of 'std::vector<_Ty>'
新秀

2
@Rookie:看来您正在使用损坏的编译器-C ++规范中的23.3.6.3定义了vector :: data。尝试向供应商提交错误或获取更好的编译器。
克里斯·多德

1
@克里斯·多德我有同样的错误。我使用Visual Studio 2008中
bodacydo

34
@ChrisDodd:vector::data()C ++ 11的
新手-HighCommander4

我使用Visual Studio 2012,并且他们必须添加vector :: data(),因为我经常使用它。
罗伯特·斯奈德2013年

12

改用第一个元素的指针:

process_data (&something [0]);

我以为即使没有下标括号,它也会返回第一项的内存地址?

那是数组,而不是向量。
史蒂文·唐

是的,只是意识到这一点,对不起。
蒂姆,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.