内存对齐问题--vs2010下位域结构体对齐规则
2012-08-08 14:59
330 查看
请写出一下代码的输出结果:
按照位域内存对齐规则并参考http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html,分析得知sizeof(s1)=16,而vs2010给出的答案是24,纠结了一下午也没给出一个明确的答案,先把疑问写出来,慢慢来求解。
对于比较难解决的问题,最好不要依赖printf,直接按F10,在监视1看了下变量s的地址是0x0012FF48,所以在memset里会出现0x0012FF48这个地址,为了把变量s在内存中所占区域清零,然后在内存1中查看0x0012FF48起始的内存块,如下图所示:
从图中可以看出vs内存对齐规则是4(int)+1(char)+3(扩展)+4(int)+4(扩展)+8(double),很明显就没按位域对齐规则来存储,而是按照普通的一个结构体来进行内存对齐,难道这是vs2010的一个小bug?待求解!
在网上搜索了一番,终于解开了谜题,http://www.diybl.com/course/3_program/c++/cppsl/20090311/160450.html# 这篇文章写得很好,解释的很清楚,对于位域存储规则的处理不同编译器处理规则不一样。(以下文字来自于http://www.diybl.com/course/3_program/c++/cppsl/20090311/160450.html#)
如果结构体中含有位域(bit-field),那么VC中准则又要有所更改:
1)
如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式;
// interface.cpp : 定义控制台应用程序的入口点。 //内存对齐 #include "stdafx.h" #include <stdio.h> #include <memory.h> struct s1 { int i:8; char j:4; int a:4; double b; }; struct s2 { int i:8; int j:4; double b; int a:4; }; struct s3 { int i; char j; double b; int a; }; struct s4 { int i:8; int j:4; int a:3; double b; }; struct s5 { int i:8; int j:4; double b; int a:3; }; struct name1 { char str; short x; int num; }; struct name2 { char str; int num; short x; }; int _tmain(int argc, _TCHAR* argv[]) { memset((struct s1 *)(0x0012FF48),0,sizeof(struct s1)); struct s1 s; s.i=1; s.j=2; s.a=3; s.b=3; printf("%d\t",sizeof(s1)); printf("%d\t",sizeof(s2)); printf("%d\t",sizeof(s3)); printf("%d\t",sizeof(s4)); printf("%d\t",sizeof(s5)); printf("%d\t",sizeof(name1)); printf("%d\t",sizeof(name2)); return 0; }
按照位域内存对齐规则并参考http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html,分析得知sizeof(s1)=16,而vs2010给出的答案是24,纠结了一下午也没给出一个明确的答案,先把疑问写出来,慢慢来求解。
对于比较难解决的问题,最好不要依赖printf,直接按F10,在监视1看了下变量s的地址是0x0012FF48,所以在memset里会出现0x0012FF48这个地址,为了把变量s在内存中所占区域清零,然后在内存1中查看0x0012FF48起始的内存块,如下图所示:
从图中可以看出vs内存对齐规则是4(int)+1(char)+3(扩展)+4(int)+4(扩展)+8(double),很明显就没按位域对齐规则来存储,而是按照普通的一个结构体来进行内存对齐,难道这是vs2010的一个小bug?待求解!
在网上搜索了一番,终于解开了谜题,http://www.diybl.com/course/3_program/c++/cppsl/20090311/160450.html# 这篇文章写得很好,解释的很清楚,对于位域存储规则的处理不同编译器处理规则不一样。(以下文字来自于http://www.diybl.com/course/3_program/c++/cppsl/20090311/160450.html#)
如果结构体中含有位域(bit-field),那么VC中准则又要有所更改:
1)
如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式;
相关文章推荐
- (原创)VB调用DLL(VC)使用结构体参数时的内存对齐及分配的问题.
- C语言的结构与联合内存对齐问题:结构或者联合大小取决于?
- 关于C语言中数据结构的内存对齐问题
- 最透彻的讲解结构体成员内存对齐问题——透彻理解哦
- 结构体内的内存对齐问题
- 内存对齐问题
- gcc 中结构体(struct)内存对齐问题分析
- 总结面试时没有回答上的内存对齐问题
- 关于 内存对齐 && sizeof 的介绍 2 —— 结构体
- Android平台,C/C++代码内存对齐问题(signal SIGBUS Error)
- 内存对齐问题
- 解决VS2010批量替换时经常由于内存较低而导致VS2010自动关闭的问题
- 结构体嵌套中的内存对齐问题
- 关于VC下结构体内存对齐问题
- 结构体在内存中的对齐规则
- C struct结构体内存对齐问题
- 结构体存储内存对齐
- 内存对齐的规则以及作用
- C语言 结构体的内存对齐问题与位域
- 内存写越界导致破环堆结构引起的崩溃问题定位经验[如报错malloc(): memory corruption或free(): invalid next size]