c++中利用sizeof运算符计算结构体大小问题探讨


  c++中提供的sizeof运算符可以方便得计算出内置类型的字节数大小,比如sizeof(int),sizeof(char),sizeof(double)的返回值分别为4,1,8,这是很容易理解的。但是将sizeof运算符用于计算结构体变量所占内存大小时,情况可能会出乎意料。

  比如,我们这里定义一个结构体如下:

1   typedef struct
2
3     {
4
5       int a;
6
7       char b;
8
9     }struct1;


 

  我们按照常理计算一下,int类型的变量为4字节,char类型的变量为1字节,那么一个struct1类型的变量肯定就为5字节,是两个成员的相加,但是在程序中实验后,我们发现,实际上sizeof(struct1)的值为8,着实让人疑惑。

  其实,结构体在被编译器编译的时候,它所占据的内存空间的大小是根据编译器来决定的,我们可以利用编译器的预编译指令来得到这个默认值。在VS2008中加入#pragma pack(show)后,编译工程文件时就会出现这样的提醒:

    warning C4810: 杂注 pack(show) 的值 == 8。

这个就是编译器默认的编译结构体时其数据成员的对齐方式。对齐方式可以理解为编译结构体时每次为其数据成员分配的内存空间的大小。如果这个分配的8字节内存用完了,那么就另外分配一块8字节的空间来继续为结构体的数据成员指定位置。比如上段代码中,首先OS分配一个8字节的内存空间给结构体,先把 int a 这个数据成员装进去,int型为4字节,这时还剩下4个字节,这足够装下一个char类型的 char b,所以这8个字节的内存空间中实际上有值的只有前5个字节,而后三个字节是没有放任何东西的,但是在计算这个结构体的大小时还是要计算入内,所以这个结构体的大小就是8字节。

  为了验证这个结论的正确性,我们再来看几个例子:

1 typedef struct
2 {
3 int a;
4 double b;
5 }struct2;

  在这个结构体中定义了一个整型和一个双精度浮点型,所占的内存空间大小分别为4和8字节。编译器默认的对齐方式为8。首先,OS为其分配一个8字节的空间, int a先装进去,这时只剩下4字节的剩余空间,放不下double b了,所以OS再为其分配一个8字节的空间,将double b装进去,所以得到的struct2类型的字节大小就是16。

  再看:

1 typedef struct
2 {
3 int a;
4 char a[6];
5 double c;
6 }struct3;

  这个结构体中有一个char a[6],数组的大小就是一个顺序存储的顺序结构,它的字节大小就是数组中每个成员的大小乘以数组的长度,这里为6字节。首先分配一个6字节的内存空间,先装下int a,由于char a[6]为6字节,所以剩下的4字节装不下,就再分配8字节,用来装下char[6]。还剩下2字节装不下double c,所以再分配8字节用来装它,所以结构体struct3的字节大小就为24字节。

扫描二维码关注公众号,回复: 6682232 查看本文章

转载于:https://www.cnblogs.com/hongfenglee/archive/2012/02/17/2355141.html

猜你喜欢

转载自blog.csdn.net/weixin_34314962/article/details/94102381