结构体大小与内存对齐

1.什么是结构体内存对齐和为什么要对齐?

元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每个元素放置到内存中时,它都会认为内存是按照自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始。

2.结构体内存怎样对齐?

1.先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。
2.该数的偏移量必须是该数大小的整数倍,否则偏移量就自动变为该数的最小倍数,然后再计算(0被看作任何数的整数倍)。
for example 1:

struct stu1
  {
  int i;
  char c;
  int j;
  };

第一个成员i的偏移量为0,i的大小为4,偏移量满足上述条件2,则第二个数的偏移量为0+4 = 4;c的大小为1,满足2,则j的偏移量为5,但不满足条件2,所以j的偏移量变为j大小的最小倍数为8,故结构体大小=最后一个成员的偏移量+最后一个成员的大小= 8 + 4 = 12。
for example 2

struct stu2
  {
  int p;
  short o;
  };

成员p的偏移量为0;成员o的偏移量为4,都不需要调整。但计算出来的大小为6,显然不是成员p大小的整数倍。因此,编译器会在成员o后面补上2个字节,使得结构体的大小变成8从而满足第二个要求。由此可见,大家在定义结构体类型时需要考虑到字节对齐的情况,不同的顺序会影响到结构体的大小
for example 3

struct stu5
  {
      short i;
      struct
  {
  char c;
  int j;
  } ss;
  int k;
  }

结构体stu5的成员ss.c的偏移量应该是8,而不是 5。整个结构体大小应该是20。

3.对齐参数如何设置?可以设置为按照任意字节数对齐吗?

在windows中,VS编译器下,默认对齐数为8;
在Linux中,默认对齐数为4
设置对齐参数可在结构体struct之前加上#pragma pack(对齐数),在struct之后加上#pragma pack;便可以设置对齐参数。

#pragma pack(4)
struct   A
            {
               int a;
               char b;
               double c;
               char d;
            };
#pragma pack;

需要注意的是对齐参数不能任意设置,只能是内置类型已有的字节数,如:char(1)、short(2),int(4),double(8)…不能是3,5…任意数。

猜你喜欢

转载自blog.csdn.net/weixin_43510732/article/details/87902129