0

我有一个 N 字节长的缓冲区,其中 N 至少为 50。此缓冲区采用非常特定的格式,其中前 4 个字节是一个无符号整数,表示缓冲区的长度(包括这四个字节)。接下来的 16 个字节是四个具有不同含义的无符号整数。接下来的 N-20 字节是一些通用的内存缓冲区。

现在,要设置此缓冲区,我会执行以下操作:

memcpy((char*)my_buf + 0, &buf_size, 4);    //buf_size is some unsigned int
memcpy((char*)my_buf + 4, &prop0, 4);    //buf_size is some unsigned int
memcpy((char*)my_buf + 8, &prop1, 4);    //buf_size is some unsigned int
memcpy((char*)my_buf + 12, &prop2, 4);    //buf_size is some unsigned int
memcpy((char*)my_buf + 16, &prop3, 4);    //buf_size is some unsigned int
//Many more bytes used as a generic buffer

但是,这似乎非常不雅。在这一点上,我想询问社区是否有一种更优雅的方法可以在给定初始地址时将特定值分配给特定的内存偏移量。

我考虑过使用结构,但 IIRC 结构不保证其成员在内存中的放置顺序,而且我不知道结构如何表示缓冲区的尾部,即通用内存空间。

4

3 回答 3

1

结构不保证其成员在内存中的放置顺序

那是假的。订单有保证。最终编译器可以引入一些填充。但是您正在使用多个 4 字节,因此不应发生填充(至少在 32 位体系结构中,您是什么?)。

看看这个线程C,特别是对这两个和C++标准的引用。

于 2012-10-31T21:16:42.523 回答
1

您至少应该使用sizeof(unsigned int)而不是 4 或 4 的倍数:

memcpy((char*)my_buf + 0, &buf_size, sizeof(unsigned int));
memcpy((char*)my_buf + 1 * sizeof(unsigned int), &prop0, sizeof(unsigned int));
memcpy((char*)my_buf + 2 * sizeof(unsigned int), &prop1, sizeof(unsigned int));
memcpy((char*)my_buf + 3 * sizeof(unsigned int), &prop2, sizeof(unsigned int));
memcpy((char*)my_buf + 4 * sizeof(unsigned int), &prop3, sizeof(unsigned int));

如果您的内存以 s 的倍数组织unsigned int,您还可以使用 unsigned int 数组:

unsigned int my_buf[X];

my_buf[0] = buf_size; // better yet, use sizeof(my_buf)!
my_buf[1] = prop0;
my_buf[2] = prop1;
my_buf[3] = prop2;
my_buf[4] = prop3;

或使用其他人已经指出的结构。

于 2012-10-31T21:23:30.553 回答
0

创建您的结构并相信内存按您所说的那样布置。

结构中的最后一个字段可以是

struct MyStruct {

   // your fields above here...
   char generic[];
};

创建结构实例时,您需要知道通用内存的大小。

MyStruct* instance = malloc(sizeof(MyStruct) + genericBytes);

要访问通用部分,请使用通用字段。

instance->generic[i] = something;

@Heisenbug 是对的,但如果填充成为问题,请在结构定义之前和之后使用 pad pragma。

#pragma pad(1)
// ... your struct
#pragma pad()
于 2012-10-31T21:19:16.610 回答