结构体共用体内存分配规律

一:字节对齐

不同操作系统里默认的对其方式存在差别,不过我见过貌似都是8 Byte对齐的,可以通过#pragma pack(n)来设定按n字节对其。

例:

#pragma pack(2)                                                      #pragma pack(4)

struct B                        struct  C

{                            {

   char  b;                        char  b;

           int    a;                         int    a;

           short  c;                         short  c;

}                           }

  针对上面两个列子,

对于结构体B:

  数据成员b自身的对其值为1,指定对其值为2,故有效对其值为1(min(2,1)),假设存放地址为0x0000;

  数据成员a自身对其值为4,指定对其值为2,故有效对其值为2(min(2,4)),存放地址的起始地址%2==0,故存放地址应该是:0x0002-0x0005

  数据成员c自身对其值为2,指定对其值为2,故有效对其值为2(min(2,2)),存放地址的起始地址%2==0,故存放地址应该是:0x0006-0x0007

  总的内存消耗为8。

  结构体B自身对其值为4(max(1,2,4)),指定对其值为2,故结构体B有效对其值为2(min(2,4)),总内存消耗8%2==0,不需要补充。

  对于结构体C:

  数据成员b自身的对其值为1,指定对其值为4,故有效对其值为1(min(4,1)),假设存放地址为0x0000;

  数据成员a自身对其值为4,指定对其值为4,故有效对其值为4(min(4,4)),存放地址的起始地址%4==0,故存放地址应该是:0x0004-0x0007

  数据成员c自身对其值为2,指定对其值为4,故有效对其值为2(min(2,4)),存放地址的起始地址%2==0,故存放地址应该是:0x0008-0x0009

  总的内存消耗为10。

  结构体B自身对其值为4(max(1,2,4)),指定对其值为4,故结构体B有效对其值为4(min(4,4)),总内存消耗10%4!=0,需要最少补充2个字节(由此可看出字对齐的弊端——内存浪费,但就换取的效率而言,这还是值得的),故总的内存消耗为12字节。

  故:sizeof(B)=8,  sizeof(C)=12.

共享体

union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。例子如下: 
union StateMachine 

char character; 
int number; 
char *str; 
double exp; 
};

一个union 只配置一个足够大的空间以来容纳最大长度的数据成员,以上例而言,最大长度是double 型态,所以StateMachine 的空间大小就是double 数据类型的大小。

结构体【内存对齐】

结构体变量的所有成员占用不同的存储空间,结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐问题。


结构体类型需要考虑到字节对齐的情况,不同的顺序会影响结构体的大小。 结构体大小等于最后一个成员的偏移量加上其大小!
#include "stdlib.h"
#include "stdio.h"
//#define NULL 0
//#define LEN sizeof(struct student)//这样就能够求长度,不同于类必须定义对象
//结构体设计到字节对齐,默认是8字节对齐
 #pragma pack(8) //按照四字节对齐
struct student1
              {      //double a;
                     int num;  // 4字节
                    char name; //1字节,4
                 int mark; // 4
              }t1; //最大为int型,应为4的倍数

struct student2
              {//最大为double,应为8的倍数
                     double d; //8
                     char name;//1,8
                     //short  c;
                    
              }t2;
//nion数据成员公用一个空间,分配的时候最大的向上取整
 union data
              {  //为int的倍数
                     int a,c;                     
                     //double d; //8
                    int i; 
                char c1;
            char c2[9]; //9但是需要4的倍数,就是12
                      
               };

 
int main()
{
   printf("s1:%d \n",sizeof(t1));
   printf("s1:%d \n",sizeof(t2));
   printf("s1:%d \n",sizeof(data));
   return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值