结构体大小和内存对齐(C语言)

导言:

结构体在内存中的大小并不是简简单单的将结构体成员的各个部分的空间进行求和即可,对于计算机而言,它有一定的计算规则,而这个计算规则和计算机的内存对齐(字节对齐)方式有关,这就涉及到计算机原理的问题了,接下来我们会介绍一下什么是内存对齐,以及举一个例子来说明如何计算结构体的大小。


内存模型:

 

假设对于1个int型数据,因为int型数据所占的空间字节数为4,计算机每次在进行存放或者读取的时候,都会存放在是4的倍数的内存地址当中,读取也是如此,都是从4的倍数的起始地址开始进行读取,如果是存放的话,如图,此时就会从4开始存放,然后下一个int型数据的存放地址就是从8开始,以此类推........

为什么计算机要这样子进行数据的存放,而不是全部的数据都挨着存放呢?

原因:假设数据是挨着存储的

        如下图所示,由于CPU读取int型数据是以4的倍数的起始地址开始读取的,每次读4个字节,我们在存放的时候,如果是挨着存放的,如下图,那么如果我们要获取int型变量a,那么CPU就要访问两次内存了,因为CPU每一次的对int型数据的访问,必须是从4的倍数的起始地址开始读取4个字节,因此在这种情况下,就需要访问内存两次了,如果我们每次都从4的倍数的地址开始存储的话,那么CPU每次读取一个int型数据,那么只需要访问内存1次.


内存对齐

由此我们引出了内存对齐的必要性,采取内存对齐这样的办法能够减少CPU访问内存的次数,这是很有必要的,这就是计算机原理中的内存对齐,CPU读数据的时候,例如对于int型数据,每次读取数据,该数据的首地址都是4的整数倍,这是CPU的规则,对于我们而言,在存储数据的时候,要符合CPU读内存的规则,别人怎么读,我们怎么放,我们要遵守规则,这样做提高了CPU的效率,内存对齐是内存中数据的存储规则,而CPU的读取规则是固定的.但不可否认的是,虽然执行的效率提高了,但是空间却浪费了,这是一种以空间换时间的办法.


结构体大小的计算规则

       结构体大小:结构体变量所占用的内存空间字节数的多少称为结构体大小.

例子:

struct Stu
{
    char c;
    int i;
    double d;
    short s;
};

计算大小:

 struct Stu st; 

                       我们可以使用sizeof(st)语句去计算结构体的大小,要注意,这块sizeof()的结果并不一定是结构体中各个成员所占空间大小之和,因为要遵守内存对齐的规则。

struct Stu st;
printf("%u,%u\n", sizeof(struct Stu),sizeof(st));

                       ·

结构体struct Stu st;中包含4个成员,CPU是以占用字节最大的数据类型的字节数为字节对齐宽度,针对于struct Stu这种类型的结构体,那么字节对齐宽度就是8字节,也就是说CPU每次取数据都是一次性8个字节的进行读取,那么关于st的数据存储的内存模型时怎么样的呢?

通过内存对齐和补齐的规则,我们发现总共需要24的字节数,因为每次取的是8字节,所以即使short s这个变量最后从16开始占用了2个字节,那么还需要补6个字节,这样才能够凑齐8个。但其实这边要注意,如果说我的结构体的定义格式是如下情况:

struct Stu
{
    char c;
    short s;
    int i;
    double d;
};

那么 struct Stu st; st的大小就是16字节了,观察以上的两种定义方式可知,虽然里面的数据成员是一样的,但是由于排列的顺序不同,导致定义出来的结构体变量的空间大小也不一样,因此建议排列的时候按照从小到大的顺序排列,那么可在一定程度上减少内存空间的占用.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值