黑马程序员技术交流社区

标题: 关于结构体所占的存储空间大小的问题 [打印本页]

作者: 墨迹的可乐    时间: 2014-4-10 14:31
标题: 关于结构体所占的存储空间大小的问题
本帖最后由 墨迹的可乐 于 2014-4-11 02:59 编辑

关于结构体所占的存储空间有一个对齐算法,就是所占的存储空间必为最大类型数长度的倍数,那么下面这个结构体的所占的存储空间为何是12,而不是8呢?
  1. #include <stdio.h>
  2. int main()
  3. {
  4. struct stu
  5.     {
  6.           int a;   //4个字节
  7.           char b; //1个字节
  8.           short c;//2个字节
  9.           char d;//1个字节
  10.     }A;
  11.     int s = sizeof(A);
  12.     printf("%d\n",s);  //输出结果为12
  13.     return 0;
  14. }
复制代码
预计结果为8,因为4+1+2+1=8,也符合对齐算法,为什么最后的结果会是12呢?



作者: 周宇华    时间: 2014-4-10 15:03
内存会进行字节对齐。就是每个类型存放地址是类型长度的整数倍。
假设a的地址是0xff00,占4字节空间,那么b的地址就是0xff04,占1字节空间,内存对齐就会空1字节空间,把c的地址放到0xff06,占2字节空间,d地址0xff08,占1字节空间,然后补齐空缺,空3字节空间,长度就=4+1+1(空)+2+1+3(空)=12;
如果要使长度=8,将d和c换一下就行。
  1. struct stu
  2.     {
  3.           int a;   //4个字节
  4.           char b; //1个字节
  5.           char d;//1个字节
  6.           short c;//2个字节
  7.     }A;
复制代码

作者: 墨迹的可乐    时间: 2014-4-10 15:24
周宇华 发表于 2014-4-10 15:03
内存会进行字节对齐。就是每个类型存放地址是类型长度的整数倍。
假设a的地址是0xff00,占4字节空间,那么b ...

原来如此,谢谢高手解惑~~~那结构体第一个成员的地址分配是不是也必须是其类型长度的整数倍?然后依次在地址上对齐?
作者: 侯金龙    时间: 2014-4-10 16:42
#include <stdio.h>
int main()
{
struct stu
    {
          int a;   //4个字节
          char b; //1个字节
          short c;//2个字节
          char d;//1个字节
    }A;
    int s = sizeof(A);
    printf("%d\n",s);  //输出结果为12
    return 0;
}
结构体是有有效对齐值的,就是数据类型的本身长度char:   1    short:    2int:   4,假设有效对齐值为N,也就是说该数据的”存放起始地址%N=0″这个老师没讲,应该不重要。
假设stu从地址空间0×0000开始排放。第一个成员变量a有效对齐值为4,所以其存放地址从0×0000到0×0003这四个连续的字节空间中符合0×0000%4=0.第二个成员变量b,其有效对齐值为1,所以存放地址为0×0004,复核0×0004%1=0,且紧靠第一个变量。第三个变量c,有效对齐值是2,可以存放在0×0008到0×0009这两个字节空间中,符合0×0008%2=0。第四个变量c,有效对齐值是1,可以存放在0×000A中,符合0×000A%1=0。所以从0×0000到0×000A存放的都是stu内容。从0×000A到0×0000=11字节,根据根据对齐算法,应该取最大字节4的整数倍为12。结构体stu所占从0×0000到0x000B共有12个字节,sizeof(A)=12;

作者: 侯金龙    时间: 2014-4-10 16:46
这些老师视频中没有,老师也说不重要,你要是不懂,也不用太纠结。
作者: 墨迹的可乐    时间: 2014-4-10 17:18
侯金龙 发表于 2014-4-10 16:42
#include
int main()
{

恩恩  谢谢指导~~
作者: 周宇华    时间: 2014-4-10 17:52
墨迹的可乐 发表于 2014-4-10 15:24
原来如此,谢谢高手解惑~~~那结构体第一个成员的地址分配是不是也必须是其类型长度的整数倍?然后依次在 ...

对。第一个成员是4字节的,它只能被分配在0、4、8、c地址上;8字节的话就只分配在0、8地址上。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2