2012-01-15 10 views
8

私はこのトピックについて探していたと私はSTDに配列[]に変換する多くの方法::ベクトル、使用するような発見への配列のコピー:中のstd ::ベクトル

assign(a, a + n) 

かを、直接コンストラクタ:

std::vector<unsigned char> v (a, a + n); 

ものは私の問題を解決し、それが可能(かつ正しい)であれば、私がやって疑問に思っ:

myvet.resize(10); 
memcpy(&myvet[0], buffer, 10); 

私は疑問に思ってこの私は、次のコードを持っているので:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    bufferRead.resize(totalToRead); 
    DWORD totalRead; 
    ReadFile(mhFile, &bufferRead[0], totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 

    return IDiskAccess::READ_OK; 
} 

(私はポストを簡素化するためのReadFile関数のエラー処理を削除した):

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    uint8_t* data = new uint8_t[totalToRead]; 
    DWORD totalRead; 
    ReadFile(mhFile, data, totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 
    bufferRead.assign(data, data + totalRead); 
    delete[] data; 

    return IDiskAccess::READ_OK; 
} 

をそして、私はやりたいです。

働いていますが、安全でないことを誇りに思います。私はそれが大丈夫です、ベクトルによって使用されるメモリが連続していると信じていますが、私はこのようにベクトルを使用している人は見たことがありません。

このようなベクトルを使用するのは正しいですか?他に良いオプションはありますか?

答えて

8

はい安全ですstd::vector C++標準では、要素が連続したメモリ位置に格納されることが保証されています。

C++ 11標準:

23.3.6.1クラスtemplatevector概要[vector.overview]

ベクトルは、ランダムアクセス反復子をサポートするシーケンス容器です。さらに、終わりに一定時間の挿入および消去操作をそのサポート(償却)する。途中での挿入と消去は線形時間を要します。ストレージ管理は自動的に処理されますが、効率を改善するためのヒントを与えることができます。 ベクトルの要素は、と連続して格納されています。つまり、ifvがベクトルであり、Tがbool以外の型であることを意味する。& v [n] == & v [0] + n for all0 < = n < v 。サイズ()。

1

のサイズ変更を最初に実行しても問題ありません。 vector

vector<int> v; 
v.resize(100); 
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int)); 
+3

He *は最初にリサイズします(関数の最初の行を参照)。 – celtschk

+1

私は彼がそうしなかったことを意味していませんでした。私はその重要性を強調していました。 – TheBuzzSaw

+1

あなたはそれを暗示する*の意味がないかもしれませんが、そうしました。 – celtschk

2

メモリしたがって、それは(あなたがもちろん、あなたが割り当てられている以上のものをコピーしないと仮定して)それにmemcpyに完全に安全である、連続して割り当てられることが保証され、unsigned char型のPODです。

1

はい、memcpyを使用するソリューションは正しいです。 vectorが保持するバッファは連続しています。しかし、タイプセーフではないので、assignまたはstd::copyを好む。

5

はい、それは問題ありません。あなたの見た目がよければ、&myvet[0]の代わりにmyvet.data()を使っても構いませんが、どちらも同じ効果があります。また、状況が許せば、代わりにstd::copyを使用して、より多くの型安全性と他の全てのC++標準ライブラリを利用することができます。

vectorが使用するストレージは連続していることが保証されているため、バッファとして使用するなどの機能に適しています。

vectorは、それらの操作のいずれかにそのバッファのサイズを変更して無効にする可能性があるため、あなたがdataまたは&v[0]から取得ポインタを使用している間、あなたは(それにpush_backなどを呼び出すような)vectorを変更しないことを確認しますポインタ。

3

このアプローチは正しいですが、それは標準によって必要とされる連続したメモリを持つベクトルにのみ依存します。私は、C++ 11ではバッファへのポインタを返すベクトルに新しいdata()メンバ関数があると考えています。また、memcpyの場合、配列のサイズではなく、バイトサイズで渡す必要があることに注意してください。

関連する問題