字节数组及其大小的良好表示

时间:2013-04-08 22:20:31

标签: c++ bytearray

你如何很好地表示字节数组及其大小?我想存储(在主存储器或文件中)原始字节数组(无符号字符),其中前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的大小和数据部分。但它看起来仍然很难看。你能推荐另一种方法吗?

3 个答案:

答案 0 :(得分:5)

除非你有一些压倒性的理由不这样做,只要做惯用的事情并使用std :: vector&lt; unsigned char&gt;。

答案 1 :(得分:2)

您正在有效地重新发明"Pascal string"。然而

 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不同,它实际上将大小和数据存储在一起,因此您可以在一次操作中将其写入文件。记忆位置更好。

尽管如此,std::vector已经过测试并且为您实现了许多有用的算法这一事实使它非常具有吸引力。

答案 2 :(得分:2)

我会使用std::vector<unsigned char>来管理内存,并在你需要这样的东西时编写一个转换函数来为你创建一些iovec类似的结构。

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

使用iovec,如果您需要在单个系统调用中同时写入长度和数据,则可以使用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);
}