web-dev-qa-db-ja.com

コピーせずにC ++ std :: vectorとC配列を変換する

データを明示的にコピーせずに、std :: vectorとその基になるC配列int *の間で変換できるようにしたいと思います。

Std :: vectorは、基礎となるC配列へのアクセスを提供しますか?私はこのようなものを探しています

vector<int> v (4,100)
int* pv = v.c_array();

編集:

また、逆を行うことは可能ですか?つまり、std::vectorコピーせずにC配列から?

int pv[4] = { 4, 4, 4, 4};
vector<int> v (pv);
53
dzhelil

次のように、最初の要素へのポインターを取得できます。

_int* pv = &v[0];
_

このポインタは、ベクトルが再割り当てされない限り有効です。ベクターの残りの容量に収まるよりも多くの要素を挿入すると、再割り当てが自動的に行われます(つまり、v.size() + NumberOfNewElements > v.capacity()の場合。v.reserve(NewCapacity)を使用して、ベクターの容量が少なくともNewCapacity

また、ベクトルが破壊されると、基礎となる配列も削除されることを忘れないでください。

84
James McNellis
int* pv = &v[0]

これはstd::vector<>の場合のみであり、他の標準コンテナでは同じことはできないことに注意してください。

スコット・マイヤーズは、このトピックを本の中で幅広く扱っています。

20
Ðаn

C++ 11では、 vector :: data() を使用してC配列ポインターを取得できます。

20
m.elahi

あなたが非常に制御された条件を持っているなら、あなたはただすることができます:

std::vector<int> v(4,100);
int* pv = &v[0];

これは、ベクトルが成長する必要がない限り機能するだけであり、ベクトルは基になる配列の寿命を管理する(つまり、pvを削除しない)ことに注意してください。これは、基礎となるC APIを呼び出すときに行うことは珍しいことではありませんが、通常は明示的なint *変数を作成するのではなく、名前のない一時的なものを使用して行われます。

16
Drew Hall

サイズの変更から身を守る1つの方法は、必要な最大スペース(またはそれ以上)を予約することです。

std::vector<int> v(4,100); //Maybe need 
v.reserve(40);             //reallocate to block out space for 40 elements

これにより、Push_backsによって既存のデータが再割り当てされることはありません。

0
user1270710