内存对齐以及如何关闭内存对齐
Posted alexbai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存对齐以及如何关闭内存对齐相关的知识,希望对你有一定的参考价值。
内存对齐以前有接触过,最近又碰到好几次,特整理记录一下。
首先为什么需要内存对齐?
内存对齐(memory alignment).为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。也就是说“内存对齐”应该是编译器的管辖范围,非常依赖平台。
先来看下面的结构体:
1 struct _Test{ 2 int a; 3 int b; 4 char c; 5 }A;
sizeof(A)=?(32位机器)
在32位机器上,如果内存对齐,sizeof(A)=12。
那么如何关闭内存对齐呢?
有两种方式:添加预处理指令 #pragma pack(1) 或者 __attribute__ ((packed))
1 添加预处理指令 #pragma pack(1)
#paragma pack(1)预处理指令的作用是结构体在分配内存时俺一个字节对齐。
1 #include<stdio.h> 2 #pragma pack(1) 3 struct _Test{ 4 int a; 5 int b; 6 char c; 7 }A; 8 void main() 9 { 10 printf("sizeof(A) = %d\\n",sizeof(A)); 11 }
输出结果 就是9。
这里说明一下,如果用了#paragma pack(1)预处理指令,则整个文件中都会关闭内存对齐,如果只想对其中某个或某几个结构其关闭呢,这是就要用到第二种方法了。
2 利用__attribute__ ((packed))指令
1 #include<stdio.h> 2 //#paragma pack(1) 3 struct _TestA{ 4 int a; 5 int b; 6 char c; 7 }__attribute__ ((packed))A; 8 9 struct TestB{ 10 int a; 11 int b; 12 char c; 13 }B; 14 15 void main() 16 { 17 printf("%d\\n",sizeof(A)); 18 printf("%d\\n",sizeof(B)); 19 }
输出结果是 9 12
但是__attribute__ ((packed))这种语法只能在GCC下编译通过,Visual Sudio不支持这种语法,编译不过(仅在VS2008测试过,更高版本是否支持没有测试)。
3. 如果想在Visual Sudio下也能编译,可以采用下面这种方法
1 #include<stdio.h> 2 3 #pragma pack(push) 4 #pragma pack(1) 5 struct _TestA{ 6 int a; 7 int b; 8 char c; 9 }A; 10 #pragma pack(pop) 11 12 struct TestB{ 13 int a; 14 int b; 15 char c; 16 }B; 17 18 void main() 19 { 20 printf("sizeof(A) = %d\\n",sizeof(A)); 21 printf("sizeof(B) = %d\\n",sizeof(B)); 22 }
输出结果是 9 12。
其实就是在不使用默认内存对齐的结构提前加上 #pragma pack(push) #pragma pack(1) ,然后在结束的地方加上 #pragma pack(pop)
以上是关于内存对齐以及如何关闭内存对齐的主要内容,如果未能解决你的问题,请参考以下文章