个人理解—数据结构 3 linux下的结构体

        上一章节,说到了结构体相关话题,但所有实验以及结论都是来源于win10环境下CodeBlocks的IDE工具得出的结论,结尾也提到,在默认情况下,win10环境下和linux gcc编译器所获得结果不同。现在我们在32位ubuntu(14.04-i686)环境下使用系统自带gcc(gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4) )版本对上一章内容进行编译。

        结构体内容如下:

struct Data
{
   char aa;
   char bb;
   char cc;
   char dd;
   char ee;
   int a;
   double b;
   int c;
   char d;
   short e;
   char f;
};

 printf("Data-size=%d\n",sizeof(struct Data));

        编译指令为:

gcc text.c 

        运行结果为:

Data-size=32

        与在win10环境下进行编译结果不同,在32位linux环境下对该结构体进行编译,结构体所占有空间从原本的48字节变为了32字节,数据存放情况如下所示。

        观察数据在内存中的存放情况,我们可以看出,除了double数据是8字节对齐外,其余数据均按照4字节进行对齐。char aa~dd占有连续的一行4字节,当char ee只能存放在下一行的的开头部分,char ee接下来数据为int类型占有4字节空间,按照linux的内存对齐优化原则,只能将其存放在char ee的下一行,char ee的后面连续三字节空间被优化为char ee空占部分。接下来的double不再像win10环境下编译器优化规则一样,只能放在偶数位行数,而实可以存放在任意连续两行,在此处,我们观察前后对齐规则不难看出,gcc编译器默认规则下不再按照最大类型对上下类型数据对齐方式进行约束,而是根据4字节进行内存对齐,double数据后接int c,数据刚好占有一行4字节,之后接char d和short e存放方式与win10环境下编译器相同,short按照偶数列对齐,到了char f由于后续无内容,按照4字节对齐,依旧将内存进行开辟,最后得到32字节内存空间。

        那么,可不可以不使用内存对齐呢,毕竟嵌入式产品有些内存小的可是寸土寸金啊,当然可以,在内存结构体后加上如下指令即可。

struct Data
{
   char aa;
   char bb;
   char cc;
   char dd;
   char ee;
   int a;
   double b;
   int c;
   char d;
   short e;
   char f;
}__attribute__((packed));

        该指令,旨在根据实际内存占用情况对内存进行对齐,用多少空间就开辟多少空间,int类型一行只剩下3字节空间放不下,不存在的,先放3字节再把最后1字节放在下一行,取数据时按照在之前提到的数据拼接方法对数据进行拼接即可,如果是内存优化是空间换时间,那么不使用内存对齐就算用时间换空间了,使用__attribute__((packed))实际内存使用情况对内存空间进行开辟,内存占有情况如下:

Data-size=25

         数据存放情况如下所示:

       

        内存对齐指令,无论是linux还是win10环境下均适用,参数为packed时,用多少空间开多少空间对齐方式也就是1字节对齐(实验aligned (1)无效),packed参数还可以替换为aligned (n),其中n就算对齐字节数。值得一提的是,在win下规定aligned (4)或1,2,8,内存空间依旧为40,因为对齐字节小于等于double(8字节)所以并不会对对齐方式造成影响,依然会根据最大字节数进行内存开辟。在win环境下当内存对齐来到16时,内存开辟空间将会达到48字节,但linux-gcc依然是32字节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值