在C语言中,我们经常使用结构体(struct) 。对于结构体的描述,很多C语言的书中会提到结构体所占用的内存与其内的成员在结构体中的声明顺序有关,但是很少有书讲述了结构体占用的内存与结构体的成员声明顺序如何相关的(即结构体在内存中的对齐方式是怎么样的)。
首先我们来看以下代码的输出结果:
#include<stdio.h>
#pragma pack(2)
struct T...{
char i;
int d;
char ii;
};
#pragma pack()
int main(int argc,char * argv[])
...{
printf("%d ",sizeof(struct T));
return 0;
} 最后输出的结果为:8。
语句#pragma pack(2)的作用是定义了结构体的对齐方式,在这里指定了是按规2字节对齐,在这里我们用PPB来表示该指令指定的对齐字节数,上述代码中的PPB=2。
结构体的内存对齐规则是:
每个成员分别按自己的对齐字节数和PPB(指定的对齐字节数)两个字节数最小的那个对齐,并能最小化长度。
复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。
结构体对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。
我们按上面的规则来分析上述代码的输出结果为什么是8,分析如下:变量i默认为1字节,PB=2,所以i按1字节对齐。
变量d默认为4字节(在32位机器中int为4字节),PB=2,所以d按2字节对齐。
变量ii默认为1字节,PB=2,所以ii按1字节对齐。
此时结构体的计算出的字节数为7个字节。最后按规则3,结构体对齐后的字节数为8。可以用图1来示意结构体的字节对齐情况。 文章出处:http://www.diybl.com/course/3_program/c++/cppjs/2008918/143347.html7怎么出来的?
首先我们来看以下代码的输出结果:
#include<stdio.h>
#pragma pack(2)
struct T...{
char i;
int d;
char ii;
};
#pragma pack()
int main(int argc,char * argv[])
...{
printf("%d ",sizeof(struct T));
return 0;
} 最后输出的结果为:8。
语句#pragma pack(2)的作用是定义了结构体的对齐方式,在这里指定了是按规2字节对齐,在这里我们用PPB来表示该指令指定的对齐字节数,上述代码中的PPB=2。
结构体的内存对齐规则是:
每个成员分别按自己的对齐字节数和PPB(指定的对齐字节数)两个字节数最小的那个对齐,并能最小化长度。
复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。
结构体对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。
我们按上面的规则来分析上述代码的输出结果为什么是8,分析如下:变量i默认为1字节,PB=2,所以i按1字节对齐。
变量d默认为4字节(在32位机器中int为4字节),PB=2,所以d按2字节对齐。
变量ii默认为1字节,PB=2,所以ii按1字节对齐。
此时结构体的计算出的字节数为7个字节。最后按规则3,结构体对齐后的字节数为8。可以用图1来示意结构体的字节对齐情况。 文章出处:http://www.diybl.com/course/3_program/c++/cppjs/2008918/143347.html7怎么出来的?
解决方案 »
- Button控制OnLButtonDown问题请教
- fstream打开一个文件写的时候,用seekp移到第8个字节开始写,但文件本身只有4个字节长,会有什么结果?
- 菜鸟问题,关于内存映射文件
- 怎么在无文档视图支持的MFC程序里使用CListView视图
- 在线求助!
- sizeof()怪问题求助!!!!!
- 程序运行半道,自已消失了。不是不内存有溢出啊?
- ATL COM组件,放在IE中,如果按了ALT+F4或者 X IE就会关闭,在组件里怎么能阻止IE关闭? 100分奉送,万分感谢!!!
- 关于NTSERVICE的问题
- tree 控件中单击+号产生什么事件?
- 如何获得进程的权限?
- 如何禁用Webbrowser控件用鼠标滚轮改变字体大小的功能?
>>变量d默认为4字节(在32位机器中int为4字节),PB=2,所以d按2字节对齐。
>>变量ii默认为1字节,PB=2,所以ii按1字节对齐。 原作者没表达清楚意思,也可能有理解错误的含义,总之有点混淆。实际上,如果 pack(2);
那么,
i 占位 2
d 占位 4
ii 占位 2作者把最后一个单独考虑了,他的意思是 2 (i+对齐) + 4(d) + 1(ii) = 7, 最后再加对齐 = 8。
struct T...{
char i;
int d;
char ii;
};
#pragma pack()
这个表示是按照2字节来对齐数据,首先分配2字节给成员变量i,分配完成后,还剩一字节,没法容纳成员变量d,此时会再分配2字节,还是容纳不下,就在分配两字节,这是刚好容纳下成员变量d,此时就已分配6字节,最后一个变量ii还是分配2字节,所以最终结果是8字节