深入结构体——内存对其

①why——为什么?为什么要这么做?理由何在?原因是什么?

        为什么要在C语言中要进行内存对齐呢?如果不对齐会发生事情呢?

        个人见解

                在结构体里面保存的是什么呢?是变量的声明,在我们没有进行实例化之前,没在内存中创建栈帧,当使用的时候会创建栈帧以保存变量,那么就必然会去访问变量,那么计算机底层是怎么访问变量的呢?如果计算机是64位机,那么每一次都会访问8个字节,32位机……以此类推。计算机在访问变量的时候会读取出来进行一系列的操作,那么为什么要采取这种内存对其的策略呢?我们先来看一下下方草图:

 

         计算机会一个字一个字的读取,然而想要读取变量i的时候,就出现了两种情况,第一种是没有内存对其的,读取i要2次,第二个是采用了内存对其的,用了一次。可以看见采用了内存对齐的变量更效率

官方解释:

        1. 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能
在某些地址处取某些特定类型的数据,否则抛出硬件异常。
        2. 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

②what——是什么?目的是什么?作什么工作?

        内存对其的本质关注的是结构体中变量的所占空间大小,以及存储形式。会根据对其规则来进行存储。

对其规则:

        1. 第一个成员在与结构体变量偏移量为0的地址处。
        2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

        对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。vs默认的对其数大小为8

        3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
        4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

接下来让我们根据上面的规则

猜一猜这段代码输出的结果是多少?

typedef struct test
{
	char c1;	//1
	int i;		//4
	char c2;	//1
}test;

int main()
{
	printf("sizeof(test) :: %d\n", sizeof(test));
	return 0;
}

答案是12.答案是怎么得来的呢?

来梳理一下过程:

1、首先char 占一个字节,int 占4个字节

2、根据规则1,那么偏移数为0的位置就是c1,此时一个字节占用,当前位置0,下一个位置1;

3、根据规则2,可以算出对其数为Min(4, 8) = 4,因此i 的起始偏移位置为4,那么中间就必然空着3个位置,当前位置7, 下一个位置8;

4、根据规则2,可以算出其对其数为1,8是1的整数倍,因此c2的偏移位置为8,当前位置8,下一个位置9;

5、变量已经全部存储,根据规则3,先求出最大所有成员的最大对其数MAX(1, 4) = 4; 但是此时的位置正在8这个位置,共占用9个字节,不满足条件3,改变位置,增加占用字节,偏移位置调整至11,至此,结构体总大小运算结束,占用12个字节,下图为具体存储形式,看到这里相比大家和我一样想到如何优化这个结构体的变量了吧,那就是尽量合理利用每一个变量的位置。

 上面的运算步骤大家都已经看了,那么接下来我们一起看这段代码会占用多少字节空间呢?

typedef struct test
{
	double d;
	char c1;
	int i;
	char c2;
}test;

int main()
{
	printf("sizeof(test) :: %d\n", sizeof(test));
	return 0;
}

答案是24,如果算错的小伙伴一定要画图检验以下!!!

 但是到现在我们还没有看到规则4是如何运用的,那么接下来让我们看下一段代码

大家也来猜猜结果是多少吧?

typedef struct test
{
	double d;
	char c1;
	int i;
	char c2;
}test;
struct  test1
{
	double d2;
	test t1;
	int i;
};

 答案是40,那么这里是怎么得来的呢?

1、根据规则1,此时偏移位置从0开始,当前位置7,下一个位置8;

2、该结构体的大小为24,根据规则4,test结构体中的最大对其数为8(double),因此此处的首位置要为8的整数倍,目前刚刚好,直接从偏移位置8处开始存储,当前位置31,下一个位置32;

按照上面的规则来计算就可以得出答案40。

到这里呢,本期的结构体大小计算就接近尾声了,也感谢花时间看我的文章!!!

内容若有差错,恳请指正!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值