c语言之内存对齐

从结构体的长度问题说起

在学习结构体的时候,老师留下了一个很有意思的问题:

#include<stio.h>
#include<string>
struct Node
{
	char name;
	int string;
	char ssex;
	
};
int main()
{
	int size;
	size = sizeof(Node);
	printf("%d   ", size);
	system("pause");
	return 0;
}

很明显,我们是在求一个结构体所占的字节个数;如果没有接触到内存对齐的概念,大概率会脱口而出一个答案:6。因为char占一个字节,int占4个字节,1+4+1=6,所以结构体的所占字节大小是6。当然,这是错误的,当我们打开编译器编译运行的时候,发现结果给的是:12。而我们仅仅调换一下结构体中的顺序,

#include<stio.h>
#include<string>
struct Node
{
	char name;
	char ssex;
	int string;

};
int main()
{
	int size;
	size = sizeof(Node);
	printf("%d   ", size);
	system("pause");
	return 0;

此时编译器编译运行的时候,我们会发现,运行的结果又是:8;到底结果是如何出来的,值得探讨。

内存对齐规则

1)结构体变量的首地址是其最长基本类型成员的整数倍

2)结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍

3)结构体的总大小为结构体最宽基本类型成员大小的整数倍

具体规则摘自百度百科,直接根据以上规则来进行讲解吧。
对于以上第一个程序,由于结构体的第一个数据类型是char,毫无疑问,根据规则1,占1个字节,所以在此时结构体的字节数是1。而到了int型时,由于int占4个字节,根据规则2,则必须是由偏移量,使其长度是4的倍数开始,所以,增加了3个偏移量,从4开始,加上int所占的4个字节,结构体的长度来到了8。而到了最后一个char,所占字节个数是1,但是根据规则3,总得大小必须是最宽类型整数倍,所以从8开始的时候,毫无疑问需要加上1,以及3个偏移位,使其总长度来到12来保证3个规则全部满足。所以最终的结果来到了12。

而对于第二个程序,由于结构体的第一个数据类型是char,毫无疑问,根据规则1,占1个字节,所以在此时结构体的字节数是1,而第二个也是char,只需要继续加1即可,总长度来到了2,到了第三个int类型,因为int占4个字节,根据规则2,则必须是由偏移量,使其长度是4的倍数开始,所以,增加了2个偏移量,首地址来到了4,从4开始,加上int所占的4个字节,结构体的长度来到了8。
再来看个例子:

#include<stdio.h>
#include<string>
struct Date
{
	char dada;
	int name;
	int score;  
};
struct node
{
	char name;
	char sddd;
	char ssex;
	int daef; 
	Date vie; 
	double dae;  
};
int main()
{
	int size;
	size = sizeof(node);
	printf("%d   ", size);
	system("pause");
	return 0;
}

我们依然使用上述规则,从main函数自上从下开始,首先是3个char型,字节个数来到了3。而接下来的int根据以上规则,偏移一个偏移量,从4开始,加上本身的4个字节,总长度来到8。然后又遇到了一个结构体变量,目光转到前面结构体Date中,首先是char,长度来到了1,又是int,首先偏移3来到4,再加上4个字节,长度来到了8,最后再加上一个int来到了12,所以Date的总长度是12,最宽是4.所以,node中的字节数从8开始,加上12,总长度是20,。由于最后一个是double,长度为8,所以需要总长度偏移4,来到24,再加上8.所以node的总字节数是:32.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值