结构体对齐

1.为何要对齐

计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个k值的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如有这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始(64位系统,每次读写内存都能操作8字节数据,因此地址也是8的倍数),一次读出或写入8个字节的数据,假如软件能保证一个基本类型的数据都从8倍数地址开始,那么读或写一个数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。

2.如何确定上述的K值

该模数是由#pragma pack指定的数值 (未指定#pragma pack时,系统默认的对齐模数(32位系统为4字节,64位为8字节))和结构体内部最大的基本数据类型成员长度中数值较小者。下表给出32位系统和64位系统的数据类型和对应的模数(这里的模数已经是默认的#pragma pack的值和最大数据类型长度取小的值了,即为最终对应的对齐字节数):

charshortintlongfloatdoublelong longlong double

Win-32

(Windows系统

对齐比较特殊)

长度12444888
模数(K值)12444888
Linux-32长度124448812
模数(K值)12444444
Linux-64长度124848816
模数(K值)124848816

Linux 下32位系统每次读写数据都是从4的倍数的地址开始,读写4个字节(32位)数据;64位系统每次读写数据都是从4的倍数的地址开始,读写8个字节(64位)数据;对齐模数是为了读写数据时,能最小次数进行内存操作和使用最小量内存,弄懂这一点就能完全明白数据对齐的原理。

注:由上表可以看出,基本数据类型中,Linux 32位系统和64位系统只有long 的字节长度不一样,32位系统long 为4字节,64位系统long 为8字节。当然指针大小也不一样,32位系统指针 为4字节,64位系统指针 为8字节。

3.举例说明

如没有使用#pragma pack指定模数值,则按照上表取值,若如下程序使用#pragma pack(2)指定模数为2,则对齐K值为结构体内部最大的基本数据类型成员长度和#pragma pack的值取小。

gcc -m32是使用32位gcc编译程序,其运行时,按照32位系统运行;系统默认为64位。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct testSt1
{
	char c;
	long long l;
	short s;
}testSt1;

#pragma pack(2)
typedef struct testSt2
{
	char c;
	long long l;
	short s;
}testSt2;
#pragma pack()

typedef struct testSt3
{
	char c1;
	short s;
	char c2;
}testSt3;

typedef struct testSt4
{
	char c1;
}testSt4;

int main()
{
	printf("sizeof(char) = %d\n",sizeof(char));
	printf("sizeof(long long) = %d\n",sizeof(long long));
	printf("sizeof(short) = %d\n",sizeof(short));
	printf("sizeof(testSt1) = %d \n",sizeof(testSt1));
	printf("sizeof(testSt2) = %d \n",sizeof(testSt2));
	printf("sizeof(testSt3) = %d \n",sizeof(testSt3));
	printf("sizeof(testSt4) = %d \n",sizeof(testSt4));
	return 0;
}

image.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值