内存对齐如何在C ++中引用结构?

时间:2014-11-28 07:37:54

标签: c++

我做了一个发现,在将缓冲区转换为结构引用时我并不知道它本身包含数据缓冲区。

我认为这个例子最好用代码示例解释:

struct myStruct {
  int a;
  int b;
  char data[1];
};

#define TB_SIZE 5
char data[TB_SIZE] = {0x1, 0x2, 0x3, 0x4, 0x5};


void f(struct myStruct& dest) {
  dest.a = 33;
  memcpy(dest.data, data, TB_SIZE);
}

int main() {
  char buf[100];
  f(reinterpret_cast<struct myStruct&>(buf[0]));
  struct myStruct castStruct = reinterpret_cast<struct myStruct&>(buf[0]);

  printf("Src Values\n");
  for(int i = 0; i < TB_SIZE; ++i) {
    printf("0x%02x, ", data[i]);
  }
  printf("\nActual\n");
  for(int i = 0; i < TB_SIZE; ++i) {
    printf("0x%02x, ", castStruct.data[i]);
  }


  return 0;
}

这个简单程序的输出是:

Src Values
0x01, 0x02, 0x03, 0x04, 0x05, 
Actual
0x01, 0x02, 0x03, 0x04, 0x00,

将缓冲区转换为struct引用后,当我在struct中打印数据缓冲区时,似乎我们丢失了最后一个值,即。 castStruct [4]。

现在我猜这与结构的对齐问题有关,但我不确定为什么。如果我改为对指针的所有引用,程序按预期工作,另外如果我在myStruct中只有一个整数,在data []字段之前程序也按预期工作。所以我的问题很简单,内存对齐如何在C ++中引用结构?

1 个答案:

答案 0 :(得分:1)

所以我认为这种行为是预期的 - 实际上你得到的结果超出了你应该合理预期的程度:

struct myStruct castStruct = reinterpret_cast<struct myStruct&>(buf[0]);

将令人讨厌的缓冲区的内容复制到新的struct castStruct中 - 编译器只保证复制结构的实际元素 - 特别是它只复制单个字符数组。 你期望的是只获得第一个字符(因为对齐会发生额外的几个字节也被复制)。 请注意,当您从第一个缓冲区复制结构时,castStruct.data [2]引用未分配的未定义内存。