类型对齐问题与优化方案
这些天在看C++高效编程:内存与性能优化
看到一个以前触及过但未深入的东西,今天抽空仔细探索(学习)一番.
先看一个结构大小的例子:
--------------------------------
#include <iostream>
struct A { char a ; long b; char c ; long d;};
struct B { char a ; char c; long b ; long d;};
#pragma pack(push,1)
struct C { char a; long b; char c; long d;};
#pragma pack(pop)
void main(void)
{
using namespace std;
cout <<"Size of A: "<<sizeof(A) <<"bytes."
<<endl;
cout <<"Size of B: "<<sizeof(B) <<"bytes."
<<endl;
cout <<"Size of C: "<<sizeof(C) <<"bytes."
<<endl;
char ch = getchar();
}
------------------------------
运行结果:
Size of A: 16bytes.
Size of B: 12bytes.
Size of C: 10bytes.
这三个包含相同类型的数据的结构为什么时候会产生不同
的结果呢?
这些结构大小不同的原因与类型对齐有关.
一般情况下,编译器强制long 和下一个long 相邻.
因此A开头部分在内存中分布状况如下:
地址 内容
-----------------------------
00 字符a
01 未用
02 未用
03 未用
04-07 long b
08 字符c
09-11 未用
12-15 long d
-------------------------------
但结构B更紧凑些.因为虽然long b位置和上表中相同,但
字符c却利用了上面未用的空间.
地址 内容
-----------------------------
00 字符a
01 字符c
02 未用
03 未用
04-07 long b
08-11 long d
-------------------------------
到这里我们应该明白为什么A,B的大小不同了.因此在设计
结构的时候我想一个优秀的程序员应该会考虑一下顺序问
题.特别是使用结构存放数据库中的大量数据时,一个精心
设计的结构往往可以节省很多的空间.
现在看看我们的结构C.或许你会惊奇的发现它只用了10个
字节.同时你大概也知道是#pragma pack起了作用.
正是#pragma pack编译指令让编译器暂时调整对齐.
在上述的程序中,对齐被设定成1个字节.因此内存分配状
态如下:
地址 内容
-----------------------------
00 字符a
01-04 long b
05 字符c
06-09 long d
-------------------------------
程序中使用了push和pop,push改变了对齐方式,使新的对
齐方式放入堆栈,最后再pop出栈还原.这样保证程序剩余
部分对齐方式不受影响.
*相关对齐方式,不同编译器可能不同,请参阅所用编译器
使用手册. (man g++)
本文暂时讲到这里.其它优化我们下次再谈.呵.
zimmemran 2006-04-18
浙公网安备 33010602011771号