结构体字节对齐问题


一、结构体必知知识

1、结构体内成员按照声明顺序存储,第一个成员地址和整个结构体地址相同(第一个数据成员放在offset为0的地方)。

2、结构体中的某个成员地址为结构体变量的基址加上结构体变量在结构体中的偏移量。

二、结构体字节对齐有什么用?

1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2)性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。(为何需要进行两次的访问,见:https://blog.csdn.net/chen895281773/article/details/9567337)

引自:https://www.nowcoder.com/ta/review-c/review?tpId=22&tqId=31400&query=%E7%BB%93%E6%9E%84%E4%BD%93&asc=true&order=&page=1

三、如何进行内存对齐?

1.对齐规则:按结构体中最长类型字节为单位

以下代码为例:

#include <iostream>
using namespace std;

struct {
	int a;
	double b;
	short c;
}A;
//对齐单位为8个字节

int main() {
	 
	cout << "结构体变量A的大小:\t" << sizeof(A) << endl;

	return 0;
}

程序输出:
在这里插入图片描述
int占4个字节,double占8个字节,short占2个字节,最大为8个字节,因此对齐单位为8个字节。以8个字节为单位设置好内存分布。

对于int a:
4 * 0 = 0,offeset = 0的位置是空的,故0~3存放a。

对于double b:
8 * 0 = 0,offset = 0的位置存放了a
8 * 1 = 8, offset = 8位置为空,可以存放,故8~15
(4~7位置用来对齐,这里以*补充)

对于short c :
2 * 0 = 0,offset = 0存放a
2 * 1 = 2,存放a

2 * 4 = 8,offset = 8存放b

2 * 8 = 16,offset = 16为空,可以存放,16~17存放c,18 ~23用来对齐。
即:
在这里插入图片描述

注:改变结构体中成员的声明顺序可能会导致结构体变量的布局,如调换int a和double b的声明顺序:

struct {
	double b;
	int a;
	short c;
}A;

程序输出:
在这里插入图片描述
分析:对齐单位为8个字节
double b:
8 * 0 = 0,0~7存放b

int a:
4 * 0 = 0,

4 * 2 = 8,8~11c存放a

short c :
2 * 0 = 0,

2 * 6 = 12,12~13存放c,14 ~15补充*

即:
在这里插入图片描述

2.结构体嵌套的情况

字节对齐单位:按本结构体中最长类型字节与嵌套结构体中最长类型字节的较大值为对齐单位。

嵌套结构体部分存放规则:起点以下一行字节对齐单元算起。

struct myA{
	int a;
	double b;
	short c;
}A;

struct {
	char e[2];
	int f;
	double g;
	short h;
	struct myA i;
}B;
//对齐单位8个字节

程序输出:
在这里插入图片描述

分析:
1)对齐单位:struct B中最长类型字节为8个字节,嵌套结构体struct A中最长类型字节为8个字节,取两者最大值,则对齐单位为8个字节。

2)结构体B中struct A之前的部分按照之前的对齐规则处理。

char e[2]: 0~1
int f: 4~7
double g: 8~15
short h: 16~17

计算嵌套结构体以下一行字节对齐单元算起(18~23补*):
int a: 24~27
double b: 32~39
short c: 40~41

即:

在这里插入图片描述

3.存在指定字节对齐单位的情况(#pragma pack)

字节对齐单位:按结构体中最长类型字节和指定的对齐单位之间的较小值为对齐单位。

#pragma pack指定的数值必须为2^n。

#pragma pack(2) //指定对齐单位为2个字节
struct {
	int a;
	char b;
	short c;
	char d;
}A;
//最终对齐单位为2个字节

程序输出:
在这里插入图片描述
分析:
指定对齐单位为2个字节,结构体中最长类型字节为4个字节,取较小值2个字节为对齐单位。

int a: 0~1 和2~3
char b: 4
short c: 6~7
char d: 8
即:
在这里插入图片描述

如何进行结构体对齐部分总结自黑马程序员C语言课程,有兴趣的话可以看一下课程:https://www.bilibili.com/video/BV1GW411n7FZ?p=113

总结

结构体对齐是C/C++学习中的一个重点问题,结构体对齐有什么用处,如何进行结构体对齐也是面试中的一个经典考点,本文主要介绍这两个问题。这也是本人第一次发表的博客,其中不对的地方希望多多指正,谢谢~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值