个人理解—数据结构 2 结构体

        结构体是将多个类型数据结合的一种数据类型,但这又和数据结构有什么关系呢?现在我将来细说一下,结构体在不同编译器下所占空间的不同。

        前面说过,数据结构与算法是相辅相成的,数据的结构甚至会影响到一个算法的优劣。数据的存放方式直接影响到了算法对于的处理数据时的调度次数。现在我们将内存进行抽象,抽象为如下的一个又一个的格子。

        每一个格子代表一个字节,这些格子组成了一个新开辟的一个内存空间。现在我们向内存中写一些东西(char一个字节,shout两个字节,int4个字节,一次ldr指令将会读取一行4个字节)。

        

        现在如果我想取得内存中的char a 那么我的操作应该是:1.取出第一行所有数据。2.截取第一行数据中char a的部分,由此便得到了char a的内容。同理也就能按照如此方法得到char b的内容。那么我们应该如何得到int c的内容呢?操作为:1。取出第一行4字节数据。2.取出第二行4字节数据。3.截取第一行中int c部分内容,截取第二行中int c部分内容。4.对int c内容进行拼接。由此4步得到int c内容。是不是觉得有些麻烦?没错确实如此,如果要处理更多这样中间断开的数据,按照如此数据存储方式,每次读取都要进行上述步骤。那么有没有什么方法可以对其进行简化呢?答案是—内存对齐。

        内存对齐,顾名思义是按照一定的对其方式让存储数据进行对其,反映在内存中可以抽象为如下所示。

        

        我们可以看到,int c从刚才的存放方式,变为了独占一行的存放,现在如果想要获取int c的数据则只需要:1.取出第二行4个字节的内容,得到int c数据。步骤肉眼可见的少了,效率就提升了,这其实是一种用空间换时间的方法。

        现在我们定义一个结构体如下:(win10 intel:i7-10h)

struct Data
{
   int a;
   double b;
   int c;
   };

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

        结果为:

Data-size=24

        为什么会这样呢?我们来模拟一下数据在win10环境下使用默认编译器数据在内存中的存放方式如下所示。

        在win10的默认编译器,默认情况下,编译器将内存空间优化为如上图所示,int a与int c就算只有4字节,但因为int a后面接入为double b,所以编译器优化内存对其方式为8字节对齐。有色部分为数据实际占有内存,无色部分为内存对齐后,数据结束部分内存,所以数据的内存所占大小为实际内存+对齐部分。

        现在我们丰富一下结构体环境依然是win10+默认编译器。

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));

        结果为:

Data-size=40

        模拟一下数据在win10环境下使用默认编译器数据在内存中的存放方式如下所示。

        白色部分依然是用于对齐的占位,对于结构体而言,我们先观察,谁是所占字节最大的类型,毫无疑问是double,下一步观察数据的存放顺序,首先是char aa ~ ee,一共五个连续的char类型数据,那么更具对齐方式,前四个连续的char类型可以存放在同一行中,第五个只能自己另起炉灶,自己放一行,由于ee后面的int a不足以方向在接下来的连续三个字节中,所以只能将根据内存对齐方式,按照将余下的三个连续空间划分给ee,到了int a,自己存放在新一行的连续4字节空间中,由于int a存放结束行数为2,下一行为奇数行3行,根据编译器内存对齐规则,double将会存放在偶数行,所以第三行划分为int a的占位行,到了int c其占第6行整行4字节,但由于内存对齐原则,必须按照最大类型double(8字节)进行内存开辟,所以将6-7行进行开辟,int c之后所接类型为char 所以可放置在第7行第0列,下一类型为short,其所占2字节,对于short而言其应该放置在偶数列,所以第7行1列算做占位空间,将short放置在7行2列到3列,到此处该struct类型大小为32字节,接下来来到char f数据,自己另起一行,按照8位对齐方式进行空间开辟,所以最终struct Data类型的所占大小为40字节。

        按照最大类型所占字节进行内存对齐,这是win10默认编译器下所进行的内存对齐规则,但是!该规则只适用于win10编译器默认环境下,到了Linux-GCC编译器又将是另一番光景。

        结构体对齐方式来源于内存设计的物理限制,在此基础上不同编译器考虑到对内存使用率以及效率进行优化,在其基础上规定各自不同的内存对齐规则。

       ( 当前win10-I7-10h,IDE工具为CodeBlocks)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值