0

バイト配列とそのサイズをどのように表現しますか? 最初の 2/4 バイトがそのサイズを表す生のバイト配列 (符号なし文字) を (メイン メモリまたはファイル内に) 格納したいと思います。しかし、そのような配列に対する操作は見栄えがよくありません。

void func(unsigned char *bytearray)
{
  int size;
  memcpy(&size, bytearray, sizeof(int));
  //rest of operation when we know bytearray size
}

どうすればそれを回避できますか? 私は単純な構造について考えます:

struct bytearray
{
  int size;
  unsigned char *data;
};

bytearray *b = reinterpret_cast<bytearray*>(new unsigned char[10]);
b->data = reinterpret_cast<unsigned char*>(&(b->size) + 1);

また、bytearray のサイズとデータ部分にアクセスできます。しかし、それはまだ醜く見えます。別のアプローチをお勧めできますか?

4

3 に答える 3

2

「パスカル文字列」を効果的に再発明しています。でも

 b->data = reinterpret_cast<unsigned char*>(&(b->size) + 1);

ポインターがそれ自体を指し、ポインターが上書きされるため、まったく機能しません。

構造体の最後の要素には、サイズが指定されていない配列を使用できるはずです。

struct bytearray
{
  int size;
  unsigned char data[];
};

bytearray *b = reinterpret_cast<bytearray*>(::operator new(sizeof (bytearray) + 10));
b->size = 10;

//...

::operator delete(b);

とは異なりstd::vector、これは実際にはサイズとデータを一緒に格納するため、たとえば、1 回の操作でファイルに書き込むことができます。また、メモリの局所性が向上します。

それでも、std::vectorすでにテスト済みで、多くの便利なアルゴリズムが実装されているという事実は、非常に魅力的です。

于 2013-04-08T22:23:45.640 に答える
2

私はstd::vector<unsigned char>メモリを管理するために使用し、変換関数を作成して、そのiovecようなものが必要なときに似たような構造を作成します。

iovec make_iovec (std::vector<unsigned char> &v) {
    iovec iv = { &v[0], v.size() };
    return iv;
}

を使用iovecして、1 つのシステム コールで長さとデータの両方を書き込む必要がある場合は、そのwritev呼び出しを使用してそれを実行できます。

ssize_t write_vector(int fd, std::vector<unsigned char> &v) {
    uint32_t len = htonl(v.size());
    iovec iv[2] = { { &len, sizeof(uint32_t) }, make_iovec(v) };
    return writev(fd, iv, 2);
}
于 2013-04-08T22:34:58.787 に答える