结构体的内存对齐问题

结构体的内存对齐问题

标签(空格分隔): 结构体内存对齐


一、对齐方式

1、从偏移为0的位置开始存储;
2、如果没有定义 #pragma pack(n)
sizeof 的最终结果必然是结构内部最⼤成员的整数倍,不够补⻬;
结构内部各个成员的⾸地址必然是⾃身⼤⼩的整数倍;
3、如果定义了 #pragma pack(n)
sizeof 的最终结果必然必然是 min[n,结构内部最⼤成员] 的整数倍,不够补⻬;
结构内部各个成员的⾸地址必然是 min[n,⾃身⼤⼩] 的整数倍。

二、#pragma pack(n)

它是一个用于控制结构体成员对齐的指令,编译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。摘自 作者

三、实例

1、没加#pragma pack(n)

#include <stdio.h>
#include <Windows.h>
using namespace std;
/**************************************************************
*		结构体内存对⻬问题
*   从偏移为0的位置开始存储;
*	如果没有定义 #pragma pack(n)
*	sizeof 的最终结果必然是结构内部最⼤成员的整数倍,不够补⻬;
*	结构内部各个成员的⾸地址必然是⾃身⼤⼩的整数倍;
* 
***************************************************************/
struct S1
{
	int i ;  //起始偏移0,sizeof(i)=4; 地址0、1、2、3分配给成员i
	char j ; //起始偏移4,sizeof(j)=1;
	int a ;	 //sizeof(a)=4,内存对齐到8个字节,从偏移量为8处存放a;
	double b;//sizeof(b)=8,内存对齐到16个字节,再存放b,结构体总大小24;
};
//结构体成员的首地址必须是自身大小的整数倍
struct S3
{
	char j;//起始偏移0,sizeof(j)=1;
	float i;//sizeof(i)=4,内存对齐到4,起始偏移量为4,再存放i
	double b;//当前地址为8,是b大小的整数倍,无需对齐,直接存放成员b 8个字节
	int a;//sizeof(a)=4,内存对齐到20,再存放a,总大小24字节;
};
int main()
{
	printf("%d\n", sizeof(S1)); 
	printf("%d\n", sizeof(S3)); 
	system("pause");
	return 0;
}

输出结果:

2、添加#pragma pack(n)

#include <stdio.h>
#include <Windows.h>
using namespace std;
#pragma pack(4)
/**************************************************************
*		结构体内存对⻬问题
*   从偏移为0的位置开始存储;
*	如果定义了 #pragma pack(n)
*	sizeof 的最终结果必然必然是 min[n,结构内部最⼤成员] 的整数倍,不够补⻬;
*	结构内部各个成员的⾸地址必然是 min[n,⾃身⼤⼩] 的整数倍。
* 
***************************************************************/
struct S1
{
	int i ;  //起始偏移0,sizeof(i)=4;
	char j ; //起始偏移4,sizeof(j)=1;
	int a ;	 //sizeof(a)=4,内存对齐到8,再存放a;
	double b;//sizeof(b)=8,min[4,8]=4,当前地址12,无需进行内存对齐,直接存放b,结构体总大小20;
};

struct S3
{
	char j;//起始偏移0,sizeof(j)=1;
	float i;//sizeof(i)=4,内存对齐到4,起始地址为5,再存放i
	double b;//当前地址为8,min[8,4]=4,,无需对齐,直接存放成员b 8个字节
	int a;//sizeof(a)=4,当前地址16,为a大小的整数倍,无需对齐,总大小20字节;
};
int main()
{
	printf("%d\n", sizeof(S1)); 
	printf("%d\n", sizeof(S3)); 
	system("pause");
	return 0;
}

输出结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值