有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下):
原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。
例1:struct {
short a1;
short a2;
short a3;
}A;
struct{
long a1;
short a2;
}B;
sizeof(A) = 6; 这个很好理解,三个short都为2。
sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。
例2:struct A{
int a;
char b;
short c;
};
struct B{
char b;
int a;
short c;
};
sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。
sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。
深究一下,为什么是这样,我们可以看看内存里的布局情况。
a b c
A的内存布局:1111, 1*, 11
b a c
B的内存布局:1***, 1111, 11**
其中星号*表示填充的字节。A中,b后面为何要补充一个字节?因为c为short,其起始位置要为2的倍数,就是原则1。c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。
B中,b是char为1,b后面补充了3个字节,因为a是int为4,根据原则1,起始位置要为4的倍数,所以b后面要补充3个字节。c后面补充两个字节,根据原则3,整个B占用空间要为4的倍数,c后面不补充,整个B的空间为10,不符,所以要补充2个字节。
再看一个结构中含有结构成员的例子:
例3:struct A{
int a;
double b;
float c;
};
struct B{
char e[2];
int f;
double g;
short h;
struct A i;
};
sizeof(A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
sizeof(B) = 48; 看看B的内存布局。
e f g h i
B的内存布局:11* *, 1111, 11111111, 11 * * * * * *, 1111* * * *, 11111111, 1111 * * * *
i其实就是A的内存布局。i的起始位置要为8的倍数,所以h后面要补齐。把B的内存布局弄清楚,有关结构体的对齐方式基本就算掌握了。
分享到:
相关推荐
如果忘记用free释放,会导致所分配的空间一直占着不放,导致内存泄露。 全局区:用来存放全局变量和静态变量。存在于程序的整个运行期间,是由编译器分配和释放的。 文字常量区:例如char *c = “123456”;则”...
主要介绍了C语言编程中分配内存空间的相关函数,分别是malloc()函数和calloc()函数,需要的朋友可以参考下
浅谈C语言数据与内存分配空间和地址的联系
本实验主要是模拟在分页式管理方式下用位视图来表示内存分配情况,实现主存空间的分配和回收。用一个8*8矩阵表示内存的占用状态,1表示已经占用,0表示未占用要求输入作业名字和所需内存块。
操作系统内存分配与回收C语言模拟。包含源代码和.exe可执行文件
能够模拟动态内存分配算法对进程分配内存空间。该程序具备的基本功能为: (1)能够以空闲分区表的形式显示某一时刻内存空间的使用情况。 (2)能够创建进程即输入进程信息,包括进程名称和进程需要的内存量, 系统...
C语言实现的动态分配空间地址,程序对动态输入,输出都做了解释。
本次实验采用C编写,将内存空间定义为结构体链表,成员有作业名name[20]、作业首址s_add、作业长度length及下一节点的指针next;空闲分区表定义为结构体数组,成员有空闲区首址s_add、空闲区长度length、表项状态...
理解内存分配原理,特别是以页面为单位的虚拟内存分配方法。模拟存储管理中内存空间的管理和分配内存空间的管理分为固定分区管理方式,可变分区管理方式,页式存储管理,段式存储管理。
内存管理,c语言,编程实现;...具体包括:首先确定分配内存块管理的数据结构、空闲块的数据结构,然后完成内存分配、内存回收、空闲块管理等程序代码;最后编写模拟分配和回收过程的主函数,上机实验并取得结果数据。
(2) 假设初始状态下,可用的内存空间为640KB,并有下列的请求序列: 作业1申请130KB。 作业2申请60KB。 作业3申请100KB。 作业2释放60KB。 作业4申请200KB。 作业3释放100KB。 作业1释放130...
要求实现一个内存分配程序,其中要设置malloc()...Malloc函数可以用来分配相应空间给进程使用,而free函数用来表示程序退出时释放内存。存储分配要求首次适配方法实现,而释放内存之后会对相邻空间的空闲存储空间合并
要求实现:页表的数据结构、分页式内存空间的分配及回收(建议采用位图法)、地址重定位、页面置换算法(从FIFO,LRU,NRU中任选一种)。 提示:可先用动态申请的方式申请一大块空间,然后假设该空间为内存区域,对该...
实现首次适应算法的内存分配函数alloc_mem(int len),其中的参数为所申请的内存空间的长度,函数返回值为所分配到的内存空间的起始地址,分配时优先将空闲区的低端部分分配出去,如果空闲区较大,则留下的高端部分仍...
操作系统内存管理实验(C语言实现)
c语言怎么实现动态内存分配 我们经常会预先给程序开辟好内存空间,然后进行操作。 int arr[5] ; 对这个数组我们在定义的时候必须给提前开辟好空间,并且在程序执行的过程中,这个开辟的内存空间是一直存在的,除非...
在C语言中,我们可以使用malloc、calloc和realloc等函数来动态分配内存空间。这些函数返回一个指向分配内存空间起始位置的指针,我们可以通过这个指针来访问和操作这块内存空间。同时,我们还可以使用free函数来释放...
相比于上一个程序将文件提取出的数据导入到结构体数组中,本程序改为malloc动态分配内存空间,具体操作过程请看我的博客: https://blog.csdn.net/qq_38364548/article/details/128851020 本程序是仿照仿照严老师...
系统根据申请者的要求,按照一定的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者;当程序执行完毕或主动归还内存资源时,系统要收回它所占用的内存空间或它归还的部分内存空间。 1.程序运行...