简体   繁体   English

内存对齐如何工作以引用C ++中的结构?

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

I made a discovery which I was not aware of when casting a buffer to a struct reference which itself includes a data buffer. 我做了一个发现,在将缓冲区强制转换为本身包含数据缓冲区的结构引用时,我并没有意识到。

I think this example is best explained with a code example: 我认为最好用一个代码示例来说明此示例:

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;
}

The output from this simple program is: 这个简单程序的输出是:

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

After casting the buffer to a struct reference, when i print the data buffer inside the struct, it seems that we have lost the last value, ie. 在将缓冲区转换为结构引用之后,当我在结构内部打印数据缓冲区时,似乎我们丢失了最后一个值,即。 castStruct[4]. castStruct [4]。

Now I guess this has with alignment issues with structs to do but I am not really sure why. 现在,我猜想这与结构对齐问题有关,但我不确定为什么。 If I instead change all reference to pointers the program works as expected, Also if I just have one integer in myStruct before the data[] field the program also works as expected. 如果我改为更改对指针的所有引用,则程序将按预期运行,另外,如果myStruct中只有一个整数,则在data []字段之前,程序也将按预期运行。 So my question is simply, how does memory alignment work for a reference to a struct in C++? 所以我的问题很简单,内存对齐如何在C ++中引用结构?

So I think this behaviour is expected - in fact you get more than you should reasonably expect, in this line: 因此,我认为这种行为是预期的-实际上,您在这一行中获得的收益超出了合理预期:

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

You copy the contents of the nasty buffer into a new struct castStruct - the compiler only guarantees that the actual elements of the struct are copied - specifically it only copies a single character array. 将讨厌的缓冲区的内容复制到新的结构castStruct中-编译器仅保证复制该结构的实际元素-特别是仅复制单个字符数组。 What you would expect is to only get the first character (as it happens because of alignment an extra few bytes are also copied). 您所期望的只是得到第一个字符(由于对齐而发生的情况,还会复制另外几个字节)。 Note that castStruct.data[2] refers to unallocated, undefined memory as you have copied the struct away from your first buffer. 请注意,castStruct.data [2]引用了未分配的,未定义的内存,因为您已将结构复制到第一个缓冲区之外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM