为了让CPU能够更舒服地访问到变量,struct中的各成员变量的存储地址有一套对齐的机制。这个机制概括起来有两点:第一,每个成员变量的首地址,必须是它的类型的对齐值的整数倍,如果不满足,它与前一个成员变量之间要填充(padding)一些无意义的字节来满足;第二,整个struct的大小,必须是该struct中所有成员的类型中对齐值最大者的整数倍,如果不满足,在最后一个成员后面填充。维基百科的
Data Structure Alignment页面有如下表述:
引用
The type of each member of the structure usually has a default alignment, meaning that it will, unless otherwise requested by the programmer, be aligned on a pre-determined boundary. The following typical alignments are valid for compilers from Microsoft, Borland, and GNU when compiling for 32-bit x86:
* A char (one byte) will be 1-byte aligned.
* A short (two bytes) will be 2-byte aligned.
* An int (four bytes) will be 4-byte aligned.
* A float (four bytes) will be 4-byte aligned.
* A double (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux.
* A long double (twelve bytes) will be 4-byte aligned on Linux.
* Any pointer (four bytes) will be 4-byte aligned on Linux. (e.g.: char*, int*)
The only notable difference in alignment for a 64-bit Linux system when compared to a 32 bit is:
* A double (eight bytes) will be 8-byte aligned.
* A long double (Sixteen bytes) will be 16-byte aligned.
* Any pointer (eight bytes) will be 8-byte aligned.
验证程序如下:
#include <stdio.h>
struct s {
char a;
short b;
char c;
double d;
char e;
};
int main() {
struct s s1;
printf("%d, %d, %d, %d, %d\n",
(char*)(&s1.a) - (char*)(&s1),
(char*)(&s1.b) - (char*)(&s1),
(char*)(&s1.c) - (char*)(&s1),
(char*)(&s1.d) - (char*)(&s1),
(char*)(&s1.e) - (char*)(&s1));
printf("%d\n", sizeof(struct s));
return 0;
}
在64位linux下面运行这段代码的结果是:
引用
0, 2, 4, 8, 16
24
由于对齐机制的存在,实际上上面的struct在内存中是长这个样子的,共计24个字节:
struct s {
char a; //在地址为0的位置
char padding1[1]; //由于下面一个元素是short,对齐字节数为2的位数,需要补1字节
short b; //对齐到了地址为2的位置
char c; //在地址为4的位置
char padding2[3]; //由于下面一个元素是double,对齐字节数为8的倍数,需要补3字节
double d; //对齐到了地址为8的位置
char e; //在地址为16的位置
char padding3[7]; //整个struct的大小需要是对齐数最大者,也就是double的8字节的整数倍
};
如果是在32位的linux下跑上面的程序,由于double的长度还是8字节,但是对齐是4字节的了,所以前面几个成员的位置不变,而最后的padding只需要补3个字节就可以了,所以输出的结果是0, 2, 4, 8, 16及20.
对于windows,其32位和64位下double都是8字节对齐的,所以在32位和64位下跑这个程序结果都是0, 2, 4, 8, 16及24.
最后,整个struct的大小的要求是对齐值最大者的整数倍,没有什么默认的4或者8的倍数一说。如果把上面程序中的a,b,c,d,e的类型全变成char,那么最后的他们的地址会是0,1,2,3,4,整个struct的大小 sizeof(struct s)的值是5,没有任何padding发生。
以上程序实验的环境在64位centos x64上的gcc 4.1.2(32位结果加-m32参数)及Visual Studio 2008上得出。
转载自http://blog.loudly.me/2010/02/memory_alignment/
分享到:
相关推荐
内存对齐,值得一读的内容, 内存对齐,值得一读的内容, 内存对齐,值得一读的内容, 内存对齐,值得一读的内容,
### 内存对齐原理详解 #### 一、什么是内存对齐? 在计算机科学中,内存对齐(Memory Alignment)是指数据类型与内存地址之间的关系。简单来说,就是指数据结构(尤其是结构体中的成员)在内存中的起始地址应该...
这个大小是经过内存对齐调整后的结果。那么,为什么需要内存对齐呢?内存对齐是为了提高程序的执行效率和可移植性。在不同的体系结构中,CPU 对不同类型的数据的处理速度是不同的。为了提高程序的执行效率,编译器会...
了解和掌握C语言内存对齐的机制对于编写高效且性能优越的程序至关重要。特别是对于初学指针和系统底层操作的C语言学生而言,深入理解内存对齐不仅可以帮助他们写出运行更快的代码,还能帮助他们更好地理解计算机底层...
sizeof(结构体)和内存对齐 sizeof(结构体)和内存对齐是C语言中一个重要的概念,它们之间存在着紧密的联系。sizeof(结构体)是指结构体在内存中的大小,而内存对齐是指编译器为了提高程序的效率和可移植性,对内存...
内存对齐是计算机编程中一个重要的概念,尤其是在优化程序性能和保证系统兼容性时不可或缺。内存对齐,简单来说,是指在计算机系统中,数据在内存中的存储位置必须按照特定的规则进行排列,以满足处理器的访问效率和...
面试的时候内存对齐问的比较多,特从网上总结的面试题1.
内存对齐是计算机科学中关于数据结构存储的一种优化策略,主要应用于C++等低级编程语言。内存对齐的目标是确保数据在内存中的位置能够高效地被CPU访问,避免不必要的额外内存读取操作,提高程序运行速度。 在C++中...
在C语言中,内存对齐是一个重要的概念,它涉及到数据在计算机内存中的存储方式。内存对齐的主要目的是提高数据存取效率,减少CPU访问内存时的额外开销。当数据按照特定的规则排列在内存中,可以避免处理器进行不必要...
内存对齐是计算机科学中的一种优化技术,主要应用于编译器设计和编程语言实现中,目的是提高数据访问的效率和兼容性。它涉及到处理器架构、操作系统以及编程语言等多个层面。以下将详细介绍内存对齐的规则及其作用。...
### C++内存对齐原理与实践 #### 一、引言 C++作为一种高效且功能强大的编程语言,在处理数据时需要特别关注内存管理问题。内存对齐是C++中的一个重要概念,它涉及到如何在内存中排列数据以提高程序的执行效率。...
内存对齐是指在存储器中对数据的排列方式,使得每种类型的变量都从特定的内存地址开始访问,以提高存取效率。对齐的作用是使得硬件平台上的存储空间处理变得更加高效。 作用: 对齐的作用是确保程序的运行效率和...
理解内存对齐至关重要,因为它直接影响到程序的性能和跨平台兼容性。 首先,我们要明白什么是内存对齐。在计算机系统中,内存是以字节为基本单位进行分配的,但并不是所有数据都可以从任意地址开始存储。为了优化...
该文档提供了详细解决结构体sizeof问题,从结构体内变量所占空间大小,默认内存对齐大小,强制内存对齐方法,变量在内存中布局的详细分析,语言言简意赅,绝无废话,为读者解决了大量寻找书籍的烦恼,读者可以花费几分钟的...
在计算机编程中,内存对齐是一种重要的优化策略,特别是在C语言中。它涉及到数据结构在内存中的布局方式,以确保高效访问和存储。内存对齐的主要目的是提高数据存取速度,减少处理器的等待时间,并充分利用硬件的...
关于结构体的内存对齐关于结构体的内存对齐关于结构体的内存对齐