字节对齐方式_不同编译器的字节对齐

大家好,我是知秋君,一个会写博客吟诗的知秋码农。今天说一说字节对齐方式_不同编译器的字节对齐,希望能够帮助大家进步!!! 字节对齐 为什么字节对齐? 一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问

大家好,我是知秋君,一个会写博客吟诗的知秋码农。今天说一说字节对齐方式_不同编译器的字节对齐,希望能够帮助大家进步!!!

字节对齐

为什么字节对齐?

一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问

为了提高CPU访问内存中的数据的效率在给每个数据变量分配内存空间时,需考虑地址对齐

(1)自然对齐:在给数据分配内存空间时,如果各成员数据的空间的起始地址能够被数据的长度整除,结构的总大小是最大sizeof(类型)的整数倍

typedef struct _a

{

char c1;

long i;

char c2;

double f;

}a;

typedef struct _b

{

char c1;

char c2;

long i;

double f;

}b;

结构体a的长度为24,c1一个字节,i四个字节,为了对齐,C1要补齐3个字节,C2一个字节,f八个字节,为了对齐,C2要补齐3个字节,这里一共20个字节,因为总长度要是最大sizeof(double)的倍数,所以要为24个字节

结构体b的长度为16,c1一个字节,C2一个字节,补齐2字节,i四个字节,f八个字节,一共为16个字节,也是8的倍数

(2)适当对齐:在给数据分配内存空间时,如果数据的空间的起始地址能被数据的M值整除,结构的总大小是M值的整数倍

对于不同的数据都存在一个M值

当数据的长度

当数据的长度>机器字长M=机器字长

基本数据:长度对齐

数组:     以元素的M值对齐

指针:     以4字节对齐

联合体:   成员中最大的M值对齐

结构体:   成员中最大的M值(成员排序不同,所占内存大小不一样)

struct A{

char x;

int y;

short z;

}st1;

struct B{

char x;

short z;

int y;

}st2;

结构体A总长度为12,首先看M值,最大的是y,四个字节,未超过机器字节,所以M为4,x一个字节,补齐3字节,y四个字节,z两个字节,补齐2字节,一共12字节,是M的倍数

结构体B总长度为8,M值也是为4,x一个字节,z两个个字节,补齐一个字节,y四个字节,一共8个字节,是M的倍数

从上面可以看到,结构体成员是一样的,但是顺序不一样,导致了占用的空间不一样,所以我们在定义结构体成员时,最好是按字节长度从小到大定义,可以节省空间

(3)栈上对齐:函数内的变量一般都是存在栈上的,x86平台是四字节对齐,x64平台是16字节对齐

Void test(void)

{

char c =0;

int a = 4;

char str[10]= "hello";

float f = 2.0f;

f = a+c;

}

占用空间是24字节,c一个字节,补齐3字节,a四个字节,str占10个字节,补齐2字节,f四个字节,一共24字节

知秋君
上一篇 2024-07-03 15:32
下一篇 2024-07-03 15:32

相关推荐