内存对齐如何用于对 C++ 中结构的引用

How does memory alignment work for a reference to a struct in C++?

本文关键字:C++ 结构 引用 用于 对齐 何用于 内存      更新时间:2023-10-16

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

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

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 Valuesn");
  for(int i = 0; i < TB_SIZE; ++i) {
    printf("0x%02x, ", data[i]);
  }
  printf("nActualn");
  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,

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

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

所以我认为这种行为是意料之中的 - 事实上,你得到的比你应该合理预期的要多,在这一行中:

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

您将讨厌的缓冲区的内容复制到新的结构 castStruct 中 - 编译器只保证复制结构的实际元素 - 具体来说,它只复制单个字符数组。您所期望的是只获取第一个字符(因为对齐而发生的那样,还会复制额外的几个字节)。请注意,castStruct.data[2] 指的是未分配、未定义的内存,因为您已将结构从第一个缓冲区复制出来。