浅谈C++结构体的内存对齐

最近在认真学习C++基础,就此对于结构体的内存对齐做个学习笔记

                                                                                                                                                                                                                

(1)为什么需要内存对齐?

《windows核心编程》里这样说:CPU访问对齐数据时候效率最高,当数据大小的数据模数为0的时候,内存是对齐的。内存对齐牺牲空间换来更快的效率。

(2)如何去查看结构体内存结构?

IDE:VS2013  在创建项目中,选择某个.cpp文件,右键——>Properties——>Configuration Properties——>C/C++——>Command Line在右边的Additional Options中添加-d1reportSingleClassLayoutXXX   (XXX代表类名),对项目进行built ,在output中可以找到类或者结构体的内存布局。

(3)成员变量对齐原理

VS2013默认以8字节对齐,对于32位平台,默认以4字节对齐,64位平台,默认按照8字节对齐,我的测试环境默认8字节对齐。通过#pragma pack(X)可以控制对齐

首先我们来看以下结构体:

struct S1
{
	long long1;
	int int1;
	short short1;
	double double1;
	char char1;
};//Size = ?
struct S2
{
	long long1;
	int int1;
	double double1;
	short short1;
	char char1;
};//Size = ?
大家可计算一下自己是否计算正确。


①.结构体中成员以8字节对齐,且对齐地址为偶数。

比如S1中long1+int1 = 8字节,short1 是2字节但是double1是8字节所以short1后填充6字节,尾部一个char1填充7字节。S2中尾部short1 和 char1分别于16,18偏移对齐,尾部填充5字节组成8字节。

②.合理安排结构体中成员位置,可以减少存储占用量。

我们再来看以4字节对齐:

#pragma pack(4)
struct S1
{
	long long1;
	int int1;
	short short1;
	double double1;
	char char1;
};//Size = ?
struct S2
{
	long long1;
	int int1;
	double double1;
	short short1;
	char char1;
};//Size = ?
#pragma pack(4)按照4字节对齐

由上可知,结构体成员布局总是以某字节为单位的,若成员大小不足则填充,并且成员偏移总是偶数。

结构体和联合体的对齐:

union U
{
	char a[30];
	long b;
	char c[50];
	int d;
};

struct S
{
	char a[30];
	long b;
	char c[50];
	int d;
};

由上可知:联合体U中,c占50个字节,但是联合体大小并非50,根据字节对齐原则,那么是否大小应该是56呢?并不是,因为其后的int类型4字节和c占用同一段。

内存结构:c |<- 2字节 ->| d  总共是8字节。所以U的大小是50 + 2 = 52

下面的S按照字节对齐原则得出,S的大小是30+2+4+50+2+4 = 92

                                                                                                                                                                                                                                        

附带如何求结构体成员的偏移:

#define OFFSET( struc, e ) (size_t)&(((struc*)0)- >e)

将0强制转换成结构体指针指向的地址,再进行取地址操作得到成员e相对0的地址,(size_t)转换成偏移量

关于内存对齐的探究就到这里啦!  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值