lxw907304340的专栏

这个问题困扰许久,查了许多资料,网上众说纷纭,整理如下:

一.内存对齐的初步讲解

内存对齐可以用一句话来概括:

“数据项只能存储在地址是数据项大小的整数倍的内存位置上(分别为偶地址、被4整除的地址、被8整除的地址)”

例如int类型占用4个字节,地址只能在0,4,8等位置上。

例1:

#include <stdio.h>struct xx{ char b; int a; int c; char d;};

int main(){ struct xx bb; printf("&a = %p/n", &bb.a); printf("&b = %p/n", &bb.b); printf("&c = %p/n", &bb.c); printf("&d = %p/n", &bb.d); printf("sizeof(xx) = %d/n", sizeof(struct xx));

return 0;}

执行结果如下:

&a = ffbff5ec&b = ffbff5e8&c = ffbff5f0&d = ffbff5f4sizeof(xx) = 16

会发现b与a之间空出了3个字节,也就是说在b之后的0xffbff5e9,0xffbff5ea,0xffbff5eb空了出来,a直接存储在了0xffbff5ec, 因为a的大小是4,只能存储在4个整数倍的位置上。打印xx的大小会发现,是16,有些人可能要问,b之后空出了3个字节,那也应该是13啊?其余的3个 呢?这个往后阅读本文会理解的更深入一点,这里简单说一下就是d后边的3个字节,也会浪费掉,也就是说,这3个字节也被这个结构体占用了.

可以简单的修改结构体的结构,来降低内存的使用,例如可以将结构体定义为:struct xx{ char b; char d; int a; int c;};

这样打印这个结构体的大小就是12,省了很多空间,可以看出,在定义结构体的时候,一定要考虑要内存对齐的影响,,这样能使我们的程序占用更小的内存。

二.操作系统的默认对齐系数

在默认情况下,为了方便对结构体和类中数据元素的访问和管理,当结构体或类内的数据元素的长度都小于机器字长时,就以结构体或类中最长的数据元素为对齐单位。也就是说,结构体或类的长度一定是最长数据元素的整数倍。如果结构体或类内存在长度大于机器字长的数据元素,那么就以机器的字长为对齐单位。结构体或类中类型相同的连续元素将在连续的空间,和数组保持一致。

例如:(机器字长为32位)struct{ short a1; short a2; short a3;}A;class B{public: int a; static int b; B(); ~B();};struct{ float a; int b; char c;}C;求sizeof(A),sizeof(B),sizeof(C);对于A,short类型变量占2个字节,因此sizeof(A)为6;对于B,静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,因此sizeof(B)为4;对于C,考虑到数据对齐,float大小为4,int大小为4,char大小为1,因此sizeof(C)为12。原理:为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

每 个操作系统都有自己的默认内存对齐系数,如果是新版本的操作系统,默认对齐系数一般都是8,因为操作系统定义的最大类型存储单元就是8个字节,例如 long long(为什么一定要这样,在第三节会讲解),不存在超过8个字节的类型(例如int是4,char是1,long在32位编译时是4,64位编译时是 8)。当操作系统的默认对齐系数与第一节所讲的内存对齐的理论产生冲突时,以操作系统的对齐系数为基准。

例如:

假设操作系统的默认对齐系数是4,那么对与long long这个类型的变量就不满足第一节所说的,也就是说long long这种结构,可以存储在被4整除的位置上,也可以存储在被8整除的位置上。

可以通过#pragma pack()语句修改操作系统的默认对齐系数,编写程序的时候不建议修改默认对齐系数,在第三节会讲解原因

例2:

#include <stdio.h>#pragma pack(4)struct xx{ char b; long long a; int c; char d;};#pragma pack()

积极的人在每一次忧患中都看到一个机会,

lxw907304340的专栏

相关文章:

你感兴趣的文章:

标签云: