黑马程序员技术交流社区

标题: 结构体内存大小算法 [打印本页]

作者: 啊康    时间: 2014-4-9 16:46
标题: 结构体内存大小算法
      结构体所占的内存大小有一个补齐算法,我想问问大神,结构体所占内存大小是最大字节*变量的个数呢还是只要是最大字节数的个数呢?
比如一个int,一个char ,一个float那么它所占的字节数是3*8=24呢?还是4+1+8=13补齐到16呢?

作者: 一只小菜鸟    时间: 2014-4-9 17:26
后面一种,各个类型的长度相加,但结果是最大类型长度的倍数~
比如int char  int 。相加=9,最大为int=4,所以结果是4*3=12

群里还有个人说的比较好
if(只有一种类型){该类型*个数)
else(总长度/最大类型长度 +1)*最大类型长度=8 )
int char int    (9/4+1)*4=12;

作者: 程浩    时间: 2014-4-9 17:58

注意:struct 的{}后面要加上 ”;“

  1. #include<stdio.h>
  2. struct A
  3. {
  4.            int a;
  5.           double b;
  6.            char c;
  7. };
  8. struct B
  9. {
  10.            double b;
  11.             char c;
  12.             int a;
  13. };
  14. struct C
  15. {
  16.             int a;
  17.             char c;
  18.             double b;
  19. };
  20. int main(void)
  21. {
  22.           A aa;
  23.           B bb;
  24.           C cc;
  25.           printf("A = %d\n", sizeof(aa));//结果:A = 24
  26.           printf("B = %d\n", sizeof(bb));//结果:B = 16
  27.           printf("C = %d\n", sizeof(cc));//结果:C = 16
  28.           return 0;
  29. }
  30. int
复制代码
类型一般是占用四个字节,char类型一般占用一个字节,double类型一般占用8个字节。

1、结构体A首先给int a 分配四个字节,并且以4个字节对齐;然后给double b分配8个字节,发现以4个字节对齐不行,就以8个字节对齐,前面只有int a ,所以int a将占用8个字节;最后为了对齐,将给char c 也分配8给字节,所以结构体A占用了24个字节。
2、结构体B首先给double 分配8个字节,并且以8给字节对齐;然后给char c分配8给字节;最后给int a分配空间的时候发现,前面空有7个字节空间可以放下int a,int a 就和char c一起占用8个字节,所以结构体B占用了16个字节

而在GNU GCC编译器中,遵循的准则有些区别,对齐模数不是像上面所述的那样,根据最宽的基本数据类型来定。在GCC中,对齐模数的准则是:对齐模数最大只能是4,也就是说,即使结构体中有double类型,对齐模数还是4,所以对齐模数只能是1,2,4。而且在上述的三条中,第2条里,offset必须是成员大小的整数倍,如果这个成员大小小于等于4则按照上述准则进行,但是如果大于4了,则结构体每个成员相对于结构体首地址的偏移量(offset)只能按照是4的整数倍来进行判断是否添加填充。
看如下例子:

struct T
{
  char ch;
  double   d   ;
};
那么在GCC下,sizeof(T)应该等于12个字节。



作者: agelessman    时间: 2014-4-9 20:12
16个啊,int开始占四个,char占一个,后边的float本身是占8个,但是他的位置要是8的倍数,由于前边不够八个。所以就从8开始,他前边的补齐,最后是最大字符的倍数,所以就是16
作者: 侯金龙    时间: 2014-4-10 17:27
结构体所占的内存大小有一个补齐算法,我想问问大神,结构体所占内存大小是最大字节*变量的个数呢还是只要是最大字节数的个数呢?
比如一个int,一个char ,一个float那么它所占的字节数是3*8=24呢?还是4+1+8=13补齐到16呢?
结构体

分配空间时,假设从0x0000开始,要符合地址值%本身字符长度=0,int分配4个字节,分配从0x0000到0x0003储存,符合0x0000%4=0.char 储存在0x0004,符合 0x0004%1=0,float分配从0x0008到0x000F, 符合x0008%8=0
所以总共占空间为从0x0000到0x000f为16个字节,为8的整数倍不用补齐。




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