3

私が読んだことからstd::vector、連続したメモリバイト配列を必要とするc関数とインターフェースするときに使用する適切な構造です。ただし、場合によっては配列のサイズをどのように決定できるのか疑問に思っていました

私が言いたいことを説明するために、小さなサンプル プログラムを作成しました。

int main(int argc, char *argv[])
{
    std::vector<unsigned char>v;
    unsigned char p[1024];

    sprintf((char*)&p[0], "%10d", 10);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.reserve(30);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    memcpy(&v[0], &p[0], 20);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.reserve(50);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.reserve(0);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.resize(20);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.resize(0);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;

    return 0;
}

出力は次のとおりです (あまり驚くべきことではありません)。

Size: 0 Length: 0
Size: 0 Length: 30
Size: 0 Length: 30
Size: 0 Length: 50
Size: 0 Length: 50
Size: 20 Length: 50
Size: 0 Length: 50

これを行った理由は、特定のサイズのバッファーを予約してから、このメモリを を介してソケットに渡すためrecv()です。recvメモリをポインタとして渡す必要があるため、返されるものに応じてベクトル サイズが調整される方法はありません。受信したバイト数がバッファよりも小さい場合、ベクトルのサイズを何らかの方法で調整できると考えていたので、それを返すと、呼び出し元が実行できv.size()、要素の数が受信によって返されます。

上記の例のデータを見ると、使用時resize()にバッファのサイズが正しく調整されていますが、データがなくなっています。では、正しいサイズを取得するためだけに、メモリを個別に新しいベクトルにコピーする必要がありますか? これは私にとって本当に不必要なオーバーヘッドのように思えます。または、現在保持する必要がある要素の数をベクトルに伝える方法はありますか?

4

4 に答える 4

7

あなたは間違った順序で物事をやっています。

  1. resizeバッファが受け入れる最大サイズに。
  2. データを格納します (ベクトル サイズよりも小さくする必要があります)。
  3. resize実際のデータサイズに。

「データが消える」という問題は、最初にデータをコピーするときに、ベクターにサイズのみの容量がないためです(つまり、実際にデータを保持するために使用せずに事前予約されたメモリ)。再び、サイズがまだ 0 であるため、ベクトルは最初の要素 (つまり 0)reserveのみを保持する必要があることを認識しているため、データ コピーを自由に最適化できます。size()

言い換えると:

  • capacity()= 再割り当てをトリガーせずにベクトルに入れることができるデータの量。
  • size()= 実際に使用しているデータの量 (ベクトルは、再割り当て全体でそのデータのみを保持します)

さらに、現在のベクトル要素を超えてアクセスすることsize()は、未定義の動作です (整数型で動作するように見えるかもしれませんが、初期化されていないオブジェクトで何が起こるかを考えてみてください...)。そうしないでください。

于 2013-05-02T13:45:30.167 に答える
3

recvバッファに直接、次の行に沿った何か:

std::vector< unsigned char > buffer( 1024 );
buffer.resize( recv( &buffer[0], buffer.size() ) );

recv がエラー コードを返すことができるかどうかによっては、サイズを変更する前に確認する必要がある場合があります。

于 2013-05-02T13:43:04.493 に答える
0

v.reserve(n)容量を に設定しnます。

m = recv(s,&v[0],n,0)

v.resize(m)ベクトルサイズをrecvが取得したものに設定します。

于 2013-05-02T13:43:28.997 に答える