C语言面试题2(字节对齐的作用)

一、什么是字节对齐
在现代计算机中,内存空间都是按照字节(byte)划分的。从理论上讲对任何类型的变量的访问可以从任何地址开始,但实际情况是,访问特定类型的变量的时候经常在待定的内存地址访问,这就需要各种类型的数据按照一定规则在空间上排列,而不是顺序地一个接一个地排放,这种所谓的规则就是字节对齐。这么长的一段话的意思是说:字节对齐可以替身存取效率,也就是用空间换时间。
例如:

struct A
{
	char a;
	char reserved[3];//使用空间换时间
	int b;
};

在这里插入图片描述
注:其中的reserved成员对于程序并没有意义,知识起到了填补空间达到字节对齐的目的。当然,即使不加这个成员,编译器也会自动为我们补齐,加上它只是起到显示提醒。
二、为什么需要字节对齐?
以为各个硬件平台对存储空间的处理上有很大的不同,一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐,其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果高低字节进行并凑才能得到该32bit数据。显然在读取效率上下降很多。
三、几个基本概念
1、基本数据类型的自身对齐值
例如,char型数据的自身对齐值为1字节,short类型自身对齐值为2字节,int、float、long类型自身对齐值均为4字节,double类型自身对齐值均为8个字节。(32位系统)
2、结构体或类的自身对齐值
其成员中自身对齐值最大的那个值。
3、指定对齐值
通过预编译指令#pragma pack(value)来指定的对齐值value。(注:取消自定义对齐值得指令为#pragma pack())
4、数据成员、结构体和类的有效对齐值
其自身对齐值和指定对齐值中较小的那个值。
四、字节对齐的几个例子浅析
例1:设有如下两个结构体

struct A
{
	char a;
	short b;
	int c;
};
struct B
{
	short b;
	int c;
	char a;
};

那么上面两个结构体的大小是多少呢?
对于结构体A:a是char型数据,占用1字节内存;short型数据,占用2字节内存;int型数据,占用4字节内存。因此,结构体A的的自身对齐值为4,sizeof(struct A) = 8字节。由于结构体类型数据是按顺序结构一个接一个向后排列的,于是其存储方式为:
在这里插入图片描述
为了更加明显地表示“对齐”,我们可以将以上结构想象为以下的行排列:
在这里插入图片描述
对于结构体B:同理也是4字节对齐,但是sizeof(struct B) = 12字节。
在这里插入图片描述
想象为以下的行排列:
在这里插入图片描述
例2:为结构体指定对齐值

#pragma pack (2)//指定2字节对齐
struct C
{
	char a;
	int b;
	short c;
};
#pragma pack()//取消指定对齐,恢复缺省对齐

对于结构体C:由于其自身对齐值为4字节(int b),而指定对齐值2字节,因此该结构体的有效对齐值较小的2字节,那么sizeof(struct C) = 8字节。
在这里插入图片描述

#pragma pack(1)//指定1字节对齐
struct D
{
	char a;
	int b;
	short c;
};
#pragma pack()//取消指定对齐,恢复缺省对齐

对于结构体D:同理可知,由于其自身对齐值4字节(int b),而指定对齐值为1字节,因此该结构体的有效对齐值为较小的1字节,那么sizeof(struct D) = 7字节。
在这里插入图片描述
五,总结
由以上分析可知,字节对齐会造成空间上的浪费。事实上,除了结构体之外,整个程序在给每个变量进行内存分配是都会遵循对齐机制,也都会产生内存空间的浪费。但我们要知道,这种浪费是值得的,因为它换来的是效率的提高。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值