结构体中的对齐与补齐!

    申请blog已经很长时间了,一直没有时间往上写点内容,正巧最近各种巧合需要重新学习一下Linux下的开发,将好久不用的C\C++重新研究了一通,在这里就把一些我自己搞弄清楚的点写一下,一来为了巩固一下,二来给需要的朋友看一看,写的不好请多指教。

    关于结构体,从第一次接触structure时就对它感到十分惊讶,因为这是一种真正让你自己定义的类型,它将一系列相关的成员集合在一起,然后逐个去处理。如何形容这种感觉呢?很美妙!所以今天我来说一下最近总结的结构体中对齐与补齐的问题。

    首先我们来看下面的这段关于商品的结构体定义,通过sizeof(gs)我们最终可以得到这个结构体的字节数是40!那么它是如何算出来的呢?

typedef struct Goods{
char name[18];
double price;
char special;
int num;
short saled;
}gs;

    结构体的字节数应当包含了内部所有成员字节数之和,那么是否将内部各成员的字节数相加在一起就可以吗?我们来试一下,18+8+1+4+2=33?和答案40不一致吧!因此上述的想法显然是错误的,所以这里我就来说一下对齐的定义。

    所谓的对齐,其实是指在结构体当中某个成员变量的存储地址是本身占用字节数的倍数。吧啦吧啦~~什么乱七八糟的。。。好吧我来给你们解释一下(明白的大神就绕过我吧!)。这里要事先做一个说明,变量本身字节数的倍数说白了就是char字节数为1,那么起始地址就是1的倍数才可以,int是4所以就得是4的倍数,但是如果本身字节数超过了4,那么仍然按照4来计算,就譬如double本身是8但是在对齐的过程中要按照4来计算,好吧也许你还不明白,那就举个例子。

    假设我们定义了一个结构体变量a,即gs a;它的起始地址是2000,而name本身所占的字节数又是18,所以第一个成员name的结束地址为2018,下一个成员price是double类型了,其本身所占字节数为8明显超过了4,所以按照4来计算,而2018明显不是4的倍数,这就需要我们补充2个字节将其变为2020成为4的倍数,同理结束地址会变为2028,2028是special字节数的倍数,所以就可以直接在末尾添加也就是2029,同理num的的首地址要变为2032,某地址为2036。好到这里基本的对齐逻辑就讲完了,所以接着往下看。

    当我们计算到num的2036后按道理其本身是saled字节数的倍数,所以直接在末尾添加即可,但是你最终发现添加后的末地址变成了38?what?不是说好的40嘛?别急这就是补齐的意义了!

    为什么要补齐?

    上述情况下我们仅仅定义了一个变量a,但是假如我们同时定义两个变量a,b,在内存空间上,a与b是需要紧靠排列的,也就说如果不补齐那么就需要紧接着上面的2038往下排,而本身a与b的内部分布应该是相同的,也就是说b内部各成员直接的空隙相同,这就造成了一个问题,你会发现b根本无法对齐内存地址。所以才有了补齐这种做法,所谓的补齐就是补齐成最大成员的倍数!也就是末地址要是最大成员的倍数,因此就是2040,这也是为什么答案是40个字节的原因了!

    以上是对于对齐与补齐的个人介绍,还请多多指教。


已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页