生データへのstd :: vectorポインターを取得する方法?


160

配列std::vectorとして使用しようとしていますchar

私の関数はvoidポインターを受け取ります:

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

回答:


238

&somethingあなたのアドレスを与えstd::vectorたオブジェクトではなく、それが保持するデータのアドレスを。 &something.begin()が返すイテレータのアドレスを提供しますbegin()(コンパイラが警告するように、something.begin()は右辺値式であるため、これは技術的に許可されていないため、アドレスを取得できません)。

コンテナに少なくとも1つの要素があると仮定すると、コンテナの初期要素のアドレスを取得する必要があります。これは、

  • &something[0]または&something.front()(インデックス0の要素のアドレス)、または

  • &*something.begin()(によって返されるイテレータが指す要素のアドレスbegin())。

C ++ 11では、新しいメンバ関数が追加されましたstd::vectordata()。このメンバー関数は、と同様に、コンテナ内の初期要素のアドレスを返します&something.front()。このメンバー関数の利点は、コンテナーが空の場合でも呼び出すことができることです。


103
重要vector<bool>この回答の例外であることに注意してください(boolsの連続したメモリストレージはありません)。
Motti

18
明るい面では、注意することはあまりありません。これらの3つのメソッドはすべて、プロキシオブジェクトの使用を必要とし、そのプロキシを暗黙的にに変換できないstd::vector<bool>ため、コンパイルに失敗します。この回避策として、のシーケンスが必要な場合は、を使用するのが最善です。@モッティstd::vector<bool>bool*boolstd::vector<char>
ジェームズマク

確かに、注意は一般的なものであり、回答として指示されたものではありません。隣接するメモリストレージがないため、注意する必要はありません。
Motti、

7
包括的ですが、主に.data()-醜いものは見なかったふりをします&*iterator:P
underscore_d

2
ポインターはどのくらいの期間data()ライブから戻りますか?ベクトルのサイズが(push_back()やを含む他の関数を介して)大きくも小さくもならない場合、reserveポインターが、ベクトルが存続している限り存続し、正しい場所を指すことが保証されますか?
johnbakers

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()を追加している必要があります。
Robert Snyder

12

代わりに、最初の要素へのポインタを取得します。

process_data (&something [0]);

下付き括弧がなくても最初の項目のメモリアドレスを返すと思いましたか?
Tim

これは配列ではなく、ベクトルです。
スティーブンドン

ええ、すみませんでした。
Tim
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.