每个特定平台的编译器都有一个默认的对齐系数,gcc中是4,VC中貌似是8。也可以通过于编译命令#pragma pack(n)来指定该系数,其中n的值经测试只能是1,2和4.
对齐规则:
1、结构体的第一个数据成员放在相对位置为0的地方,以后每个数据成员按#pragma pack(n)中n指定的值和该数据成员自身长度中比较小的那个进行对齐。
2、数据成员完成对齐后,结构体本身也要对齐,按照#pragma pack(n)中n的值和结构体数据成员中最长的长度中较小的进行对齐。
验证(环境:gcc 4.4;sizeof(char)=1;sizeof(int)=4;sizeof(short)=2;sizeof(long)=4;sizeof(long long)=8):
1、默认情况(n=4)
struct st1 {
char ch;//长度1<n,按1对齐,0%1=0,起始相对位置=0;存放区间[0]
int num;//长度4=n,按4对齐, 4%4=0,起始相对位置=4;存放区间[4,7]
long lv;//长度4=n,按4对齐,8%4=0,起始相对位置=8;存放区间[8,11]
};
整个结构体成员对齐后所占的区间为[0,8],占12个字节,接着结构体本身对齐,成员中最长的是4,n也等于4,所以结构体本身按4对齐(即对齐系数)。
整个结构体的大小 = 比整个结构体数据成员所占的总空间大或相等且和对齐系数求模结果为0、与之距离最近的数。
本例中,12%4=0,所以结构体st1占12个字节的空间。
2、#pragma pack(1)(即n=1)
struct st1 {
char ch;//长度1=n,按1对齐,0%1=0,起始相对位置=0;存放区间[0]
int num;//长度4>n,按n对齐, 1%1=0,起始相对位置=0;存放区间[1,4]
long lv;//长度4>n,按n对齐,5%1=0,起始相对位置=5;存放区间[5,8]
};
整个结构体成员对齐后所占的区间为[0,8],占9个字节,接着结构体本身对齐,成员中最长的是4,n等于1,所以结构体本身按1对齐(即对齐系数)。
整个结构体的大小 = 比整个结构体数据成员所占的总空间大或相等且和对齐系数求模结果为0、与之距离最近的数。
本例中,9%1=0,所以结构体st1占9个字节的空间。
3、#pragma pack(2)(即n=2)
struct st1 {
char ch;//长度1<n,按1对齐,0%1=0,起始相对位置=0;存放区间[0]
int num;//长度4>n,按n对齐, 2%2=0,起始相对位置=2;存放区间[2,5]
long lv;//长度4>n,按n对齐,6%2=0,起始相对位置=6;存放区间[5,8]
};
整个结构体成员对齐后所占的区间为[0,8],占9个字节,接着结构体本身对齐,成员中最长的是4,n等于2,所以结构体本身按2对齐(即对齐系数)。
整个结构体的大小 = 比整个结构体数据成员所占的总空间大或相等且和对齐系数求模结果为0、与之距离最近的数。
本例中,10%2=0,所以结构体st1占10个字节的空间。
为什么说#pragma pack(n)中n只能是1,2,4呢?
比如3,如果n=3,在编译的时候会警告“对齐边界必须是 2 的较小次方,而不是 3”,也就是说是不起作用的,按默认对齐系数对齐。
再如8,会有什么结果?看下一例:
4、#pragma pack(8)(即n=8)
struct siz {
char v1;
long long v2;
short v3;
int v4;
};
如果8起作用,分析一下:
struct siz {
char v1;//长度1<n,按1对齐,0%1=0,起始相对位置=0;存放区间[0]
long long v2;//长度8=n,按8对齐,8%8=0,起始相对位置=8;存放区间[8,15]
short v3;//长度2<n,按2对齐,16%2=0,起始相对位置=16;存放区间[16,17]
int v4;//长度4<n,按4对齐,20%4=0,起始相对位置=20;存放区间[20,23]
};
整个结构体成员对齐后所占的区间为[0,23],占24个字节,接着结构体本身对齐,成员中最长的是8,n等于8,所以结构体本身按8对齐(即对齐系数)。24%8=0,所以占24个字节。
然而,很不幸,运行的结果是20.
接下来,用默认的对齐系数4来分析一下:
struct siz {
char v1;//长度1<4,按1对齐,0%1=0,起始相对位置=0;存放区间[0]
long long v2;//长度8>4,按4对齐,4%4=0,起始相对位置=4;存放区间[4,11]
short v3;//长度2<4,按2对齐,12%2=0,起始相对位置=12;存放区间[12,13]
int v4;//长度4=4,按4对齐,16%4=0,起始相对位置=16;存放区间[16,19]
};
整个结构体成员对齐后所占的区间为[0,19],占20个字节,接着结构体本身对齐,成员中最长的是8,n等于4,所以结构体本身按4对齐(即对齐系数)。20%4=0,所以占20个字节。与运行结果一致。
综上分析,当n=8的时候gcc仍然使用的是默认的对齐系数4.
分享到:
相关推荐
3. **内存对齐**:为了提高效率和兼容性,内存分配往往需要考虑对齐要求。易语言的内存操作需遵循Linux系统的对齐规则,确保数据在内存中的布局符合硬件要求。 4. **内存安全**:易语言在处理内存时,应避免数组...
- **内存对齐**:确保数据在内存中的位置符合特定边界,提高访问效率。 5. **进程内存管理**: - **堆和栈**:栈用于快速存取局部变量,堆用于动态分配大块内存。 - **共享内存**:多个进程可以共享同一块内存...
- **内存对齐**:为了满足处理器访问效率和数据结构完整性,内存分配时需要考虑对齐要求。 3. **内存性能分析** - **工具使用**:例如`top`、`vmstat`、`free`等命令可实时查看内存使用情况,`valgrind`用于检测...
### LINUX源代码分析—内存管理 #### 一、概述 Linux 内核 2.2.5 版本中的内存管理模块负责整个系统的物理内存分配与管理。此版本的内存管理采用了多级管理策略,包括页面级分配和内核级内存分配。其中,页面级...
8. **内存对齐**:为了优化访问速度和硬件兼容性,Linux内存管理系统会确保数据在特定边界对齐,比如CPU缓存行的大小。 9. **内存保护**:通过页表项的权限位,Linux确保进程不能非法访问其他进程或内核的内存,...
4. **内存对齐**:为了确保分配的内存满足特定的对齐要求,malloc需要处理内存对齐问题。通常,分配的内存地址必须是某些值的倍数,例如机器字的大小。 5. **大小分类**:针对不同大小的内存请求,malloc可能会有...
当分配一个新的对象时,Slab分配器会从已初始化或未初始化的slab中取出空闲对象,而不需要每次分配都进行昂贵的内存对齐和初始化操作。Slab分配器的主要数据结构包括slab、cache和object,它们协同工作以提高内存...
《深入理解Linux虚拟内存》是一本专为对Linux操作系统感兴趣的读者设计的专业书籍,它深入探讨了Linux内核如何管理和...通过阅读此书,读者将能够全面掌握Linux内存管理的核心概念,提高系统性能优化和问题排查的能力。
### ARM-Linux内存页表的建立 #### 一、概览 本文将深入解析ARM-Linux环境下内存页表的建立过程。重点在于如何通过一系列汇编指令与内核配置参数来构建并初始化ARM架构下的MMU(Memory Management Unit,内存管理...
本文旨在深入探讨Linux内核2.4.18版本中的物理内存管理机制,并重点分析物理页框管理、buddy分配器、slab分配器等关键技术。 #### 二、物理页框管理 物理页框管理是Linux内核中处理物理内存的核心部分。这一机制...
接下来是一系列宏定义,这些宏用于执行不同的内存对齐和未对齐复制操作: - `ALIGN_DEST_TO8_UP`:将目的地址向上对齐至8字节边界。 - `ALIGN_DEST_TO8_DN`:将目的地址向下对齐至8字节边界。 - `DO_REST_UP`:处理...
Ptmalloc的源代码分析涉及到内存池的管理、bin数据结构的设计、锁的使用策略、内存对齐和边界检查等多个方面。理解这些细节有助于开发者优化自己的程序,避免内存泄漏和提高内存使用效率。 综上所述,Glibc的...
4. **内存对齐**:ptmalloc确保分配的内存满足用户指定的对齐要求,以适应各种数据结构的需求。 5. **内存释放与重用**:ptmalloc在释放内存后,会尝试将相邻的空闲块合并,防止内存碎片的产生。此外,ptmalloc还...
Ptmalloc2还引入了内存池和内存对齐等机制,以提高内存分配的效率和内存利用率。 在分析Ptmalloc源代码时,我们需要关注以下几个关键组件: - **内存分配函数**:如`malloc()`, `calloc()`, `realloc()`, `free()`...
本文将基于2.6.22版本的Linux内核,深入分析其启动过程。此版本虽然较为老旧,但因其广泛的应用场景而具有重要的研究价值。内核启动过程大致可以分为三个阶段:内核自解压与重定位、Vmlinux汇编代码执行以及从`start...
这种设定是为了满足不同大小需求的同时保持良好的内存对齐。 5. **维护缓冲区**:为了减少分配、初始化、销毁和释放内存的开销,Slab分配器通常会在内存中维护一个现成的缓冲区,以便于快速响应内存请求。 #### 三...
6. **内存管理**:理解Linux中的虚拟内存机制,包括动态内存分配(malloc/free)、内存映射(mmap/munmap)以及内存对齐等。 7. **文件系统**:了解Linux文件系统模型,学习文件操作、目录操作以及硬链接和软链接的...
- **内存对齐**:为了提高性能,`malloc`通常会保证分配的内存地址满足特定的对齐要求,比如按字节对齐或处理器字长对齐。 - **内存碎片整理**:长期运行的程序可能会积累大量碎片,定期进行碎片整理可以提高内存...
结构体成员变量的位置会影响结构体占用的内存大小,因为内存对齐可以提升CPU访问速度。如果将`entry`放置在结构体的起始或结束位置,可以简化遍历过程,特别是在国内企业实践中,常将`entry`放在首位,这样`list_...