本文测试机器为X86_64架构,系统为ubuntu-16.04 LTS,gcc version 7.4.0
一、默认的内存对齐
首先,通过一个例子来介绍什么是内存对齐。
#include <stdio.h>
int main( )
{
struct data
{
float a;
char b;
int c;
};
struct data e ;
printf ( "%d\n", sizeof ( e ) ) ;
printf ( "%u %u %u\n", &e.a, &e.b, &e.c) ;
return 0 ;
}
输出为:
12
3495431596 3495431600 3495431604
主观上我们认为结构体大小是9字节,此处由于内存对齐,gcc会填充若干字节,填充规则如下:
1、结构体的起始地址按最大成员的大小进行对齐
2、每个成员按其大小进行对齐
3、结构体的大小必须是最大成员的整数倍
该实例中存在三个成员,最大成员占四个字节,所以结构体起始地址(成员a的地址)为4的倍数3495431596;由于成员a占四个字节,且成员b按1对齐,所以b的起始地址为3495431600;由于成员b只占一个字节,且成员c按4对齐,所以在b之后填充三个字节,然后再存储c。
事实上内存地址的对齐还受到 #pragma pack 的影响,下面会介绍#pragma pack的使用
二、为什么需要内存对齐
至于为什么