一、什么是字节对齐
在计算机中,内存空间是按照字节(1B = 8 bit)划分的,每一个字节都有一个编号,这就是字节的地址。理论上可以从任意起始地址访问任意数据类型的变量,但在实际使用中,访问特定数据类型变量时需要在特定的内存起始地址进行访问,这就需要各种数据类型按照一定的规则在空间上进行排列,而不是顺序地一个接一个地存放,这就是字节对齐。
如果一个变量的内存起始地址正好是其数据类型长度的整数倍,就被称作自然对齐。比如,在32系统下,假设一个int型变量的起始地址为0x00000004,那它就是自然对齐的。
1.1 C语言基本数据类型占用的字节大小
C语言基本数据类型有:
整数型:char, short, int, long, long long。
浮点型:float, double
指针类型:任意数据类型的指针变量占用的存储空间都是相同的。
我们以64位系统(x64)为例,使用 sizeof() 可以输出各个基本数据类型占用的字节长度,代码如下:
#include <stdio.h>
int main()
{
printf("sizeof(char)=%d\n", sizeof(char));
printf("sizeof(short)=%d\n", sizeof(short));
printf("sizeof(int)=%d\n", sizeof(int));
printf("sizeof(long)=%d\n", sizeof(long));
printf("sizeof(long long)=%d\n", sizeof(long long));
printf("sizeof(float)=%d\n", sizeof(float));
printf("sizeof(double)=%d\n", sizeof(double));
printf("sizeof(char*)=%d, sizeof(int*)=%d, sizeof(float*)=%d\n", sizeof(char*), sizeof(int*), sizeof(float*));
return 0;
}
运行结果:
sizeof(char)=1
sizeof(short)=2
sizeof(int)=4
sizeof(long)=4
sizeof(long long)=8
sizeof(float)=4
sizeof(double)=8
sizeof(char*)=8, sizeof(int*)=8, sizeof(float*)=8
<说明> 在32位系统(x86)上,指针类型变量是4字节;在64位系统(x64)上,指针类型变量是8字节。这跟计算机的字长有关。32位系统中,CPU一次可以存取4字节的数据;64位系统中,CPU一次可以存取8字节的数据。
二、字节对齐的原因和作用
需要字节对齐的根本原因在于CPU访问内存数据的效率问题。
(1)不同硬件平台对内存空间的存取处理方式存在不同。某些硬件平台对特定数据类型的存取只能从特定地址开始,而不允许其在内存中随意存放。
一些硬件系统对字节对齐要求非常严格,比如 SPARC系列处理器,如果取未对齐的数据会发生错误,例如:
char ch[8];
char *p=&ch[1];
int i = *(int *)p;
运行时会报 segment error,因为在第3行代码中,试图从一个奇数起始地址处读取一个int型的数据,而在Intel的x86处理器上就不会出现错误,只是效率下降。
(2)如果不按照硬件平台的要求对数据存放进行对齐处理,会影响CPU访问内存的效率。比如,对于32位系统的计算机,CPU通过数据总线访问(包括读和写)内存数据,每个总线周期从偶地址开始访问32位内存数据,内存数据是以字节为单位存放的,如果一个32位数据没有存放在4字节整除

最低0.47元/天 解锁文章
282

被折叠的 条评论
为什么被折叠?



