📄 [c++对象模型][6]sizeof与对象内存布局 - itech's blog - 博客园.htm
字号:
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st2,level) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st2,level) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st2,number) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st2,number) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st2,math_grade) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st2,math_grade) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st2,Chinese_grade) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st2,Chinese_grade) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st2,sum_grade) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st2,sum_grade) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR><BR><BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> sizeof(st3)= </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #0000ff">sizeof</SPAN><SPAN
style="COLOR: #000000"> (st3) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st3,level) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st3,level) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st3,number) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st3,number) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st3,math_grade) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st3,math_grade) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st3,Chinese_grade) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st3,Chinese_grade) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR> cout </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #800000">"</SPAN><SPAN
style="COLOR: #800000"> offsetof(st3,sum_grade) </SPAN><SPAN
style="COLOR: #800000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> offsetof(st3,sum_grade) </SPAN><SPAN
style="COLOR: #000000"><<</SPAN><SPAN
style="COLOR: #000000"> endl;<BR>}</SPAN></SPAN></DIV>
<P> </P>
<P>运行结果如下;</P>
<P><IMG
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/2009022419503035.png"></P>
<P>基于上面的对struct的测试,我们是不是有些惊呆哦,对于C++的初学者更是情不自禁的说:“我靠!原来顺序不同所占空间都不同啊,还有那个pack是啥东东啊?”,其实这里蕴含了一个内存对齐的问题,在计算机的底层进行内存的读写的时候,如果内存对齐的话可以提高读写效率,下面是VC的默认规则:</P>
<P><SPAN style="COLOR: #ff0000">1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; <BR>2)
结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍, 如有需要编译器会在成员之间加上填充字节(internal adding);
<BR>3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing
padding)。</SPAN></P>
<P><SPAN style="COLOR: #ff0000">当然VC提供了工程选项<SPAN
id=ArticleContent1_ArticleContent1_lblContent>/Zp[1|2|4|8|16]</SPAN>可以修改对齐方式,当然我们也可以在代码中对部分类型实行特殊的内存对齐方式,修改方式为#pragma
pack( n ),n为字节对齐 <BR>数,其取值为1、2、4、8、16,默认是8,取消修改用#pragma
pack(),如果结构体某成员的sizeof大于你设置的,则按你的设置来对齐</SPAN><SPAN
style="COLOR: #ff0000">。</SPAN></P>
<P>三 struct的嵌套</P>
<P>1)实例:</P>
<DIV class=cnblogs_code><IMG id=Code_Closed_Image_214953 style="DISPLAY: none"
onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_214953').style.display='none'; document.getElementById('Code_Open_Image_214953').style.display='inline'; document.getElementById('Code_Open_Text_214953').style.display='inline';"
height=16
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/ContractedBlock.gif"
width=11 align=top><IMG id=Code_Open_Image_214953
onclick="this.style.display='none'; document.getElementById('Code_Open_Text_214953').style.display='none'; getElementById('Code_Closed_Image_214953').style.display='inline'; getElementById('Code_Closed_Text_214953').style.display='inline';"
height=16
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/ExpandedBlockStart.gif"
width=11 align=top><SPAN class=cnblogs_code_Collapse
id=Code_Closed_Text_214953>Code</SPAN><SPAN id=Code_Open_Text_214953><BR><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><SPAN
style="COLOR: #0000ff">struct</SPAN><SPAN
style="COLOR: #000000"> A<BR>{<BR> </SPAN><SPAN
style="COLOR: #0000ff">int</SPAN><SPAN
style="COLOR: #000000"> i;<BR> </SPAN><SPAN
style="COLOR: #0000ff">char</SPAN><SPAN
style="COLOR: #000000"> c;<BR> </SPAN><SPAN
style="COLOR: #0000ff">double</SPAN><SPAN
style="COLOR: #000000"> d;<BR> </SPAN><SPAN
style="COLOR: #0000ff">short</SPAN><SPAN
style="COLOR: #000000"> s;<BR>}; </SPAN><SPAN
style="COLOR: #008000">//</SPAN><SPAN
style="COLOR: #008000"> 24</SPAN><SPAN
style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN
style="COLOR: #0000ff">struct</SPAN><SPAN
style="COLOR: #000000"> B<BR>{<BR> </SPAN><SPAN
style="COLOR: #0000ff">char</SPAN><SPAN
style="COLOR: #000000"> cc;<BR> A a;<BR> </SPAN><SPAN
style="COLOR: #0000ff">int</SPAN><SPAN
style="COLOR: #000000"> ii;<BR>}; </SPAN><SPAN
style="COLOR: #008000">//</SPAN><SPAN
style="COLOR: #008000"> 40</SPAN></SPAN></DIV>
<P> </P>
<P>布局:(使用VS的未发布的编译选项/d1 reportAllClassLayout 或 /d1 reportSingleClassLayout)</P>
<P><IMG
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/2009022421504116.png"></P>
<P> </P>
<P>2)实例:</P>
<DIV class=cnblogs_code><IMG id=Code_Closed_Image_220158 style="DISPLAY: none"
onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_220158').style.display='none'; document.getElementById('Code_Open_Image_220158').style.display='inline'; document.getElementById('Code_Open_Text_220158').style.display='inline';"
height=16
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/ContractedBlock.gif"
width=11 align=top><IMG id=Code_Open_Image_220158
onclick="this.style.display='none'; document.getElementById('Code_Open_Text_220158').style.display='none'; getElementById('Code_Closed_Image_220158').style.display='inline'; getElementById('Code_Closed_Text_220158').style.display='inline';"
height=16
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/ExpandedBlockStart.gif"
width=11 align=top><SPAN class=cnblogs_code_Collapse
id=Code_Closed_Text_220158>Code</SPAN><SPAN id=Code_Open_Text_220158><BR><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><SPAN
style="COLOR: #0000ff">#pragma</SPAN><SPAN
style="COLOR: #000000"> pack(4)</SPAN><SPAN
style="COLOR: #000000"><BR></SPAN><SPAN
style="COLOR: #0000ff">struct</SPAN><SPAN
style="COLOR: #000000"> A2<BR>{<BR> </SPAN><SPAN
style="COLOR: #0000ff">int</SPAN><SPAN
style="COLOR: #000000"> i;<BR> </SPAN><SPAN
style="COLOR: #0000ff">char</SPAN><SPAN
style="COLOR: #000000"> c;<BR> </SPAN><SPAN
style="COLOR: #0000ff">double</SPAN><SPAN
style="COLOR: #000000"> d;<BR> </SPAN><SPAN
style="COLOR: #0000ff">short</SPAN><SPAN
style="COLOR: #000000"> s;<BR>}; </SPAN><SPAN
style="COLOR: #008000">//</SPAN><SPAN
style="COLOR: #008000"> 20</SPAN><SPAN
style="COLOR: #008000"><BR></SPAN><SPAN
style="COLOR: #0000ff">#pragma</SPAN><SPAN
style="COLOR: #000000"> pack()</SPAN><SPAN
style="COLOR: #000000"><BR><BR></SPAN><SPAN
style="COLOR: #0000ff">struct</SPAN><SPAN
style="COLOR: #000000"> B2<BR>{<BR> </SPAN><SPAN
style="COLOR: #0000ff">char</SPAN><SPAN
style="COLOR: #000000"> cc;<BR> A2 a;<BR> </SPAN><SPAN
style="COLOR: #0000ff">int</SPAN><SPAN
style="COLOR: #000000"> ii;<BR>}; </SPAN><SPAN
style="COLOR: #008000">//</SPAN><SPAN
style="COLOR: #008000"> 28</SPAN></SPAN></DIV>
<P> </P>
<P>布局:(使用VS的未发布的编译选项/d1 reportAllClassLayout 或 /d1 reportSingleClassLayout)</P>
<P><IMG
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/2009022422022940.png"></P>
<P>总结:</P>
<P> <SPAN
style="COLOR: #ff0000"> 由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
</SPAN></P>
<P>四 空struct/class和const,static成员</P>
<P>实例:</P>
<DIV class=cnblogs_code><IMG id=Code_Closed_Image_202416 style="DISPLAY: none"
onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_202416').style.display='none'; document.getElementById('Code_Open_Image_202416').style.display='inline'; document.getElementById('Code_Open_Text_202416').style.display='inline';"
height=16
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/ContractedBlock.gif"
width=11 align=top><IMG id=Code_Open_Image_202416
onclick="this.style.display='none'; document.getElementById('Code_Open_Text_202416').style.display='none'; getElementById('Code_Closed_Image_202416').style.display='inline'; getElementById('Code_Closed_Text_202416').style.display='inline';"
height=16
src="[C++对象模型][6]sizeof与对象内存布局 - iTech's Blog - 博客园.files/ExpandedBlockStart.gif"
width=11 align=top><SPAN class=cnblogs_code_Collapse
id=Code_Closed_Text_202416>Code</SPAN><SPAN id=Code_Open_Text_202416><BR><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><SPAN
style="COLOR: #0000ff">struct</SPAN><SPAN
style="COLOR: #000000"> empty{}; </SPAN><SPAN
style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 1</SPAN><SPAN
style="COLOR: #008000"><BR></SPAN><SPAN
style="COLOR: #0000ff">struct</SPAN><SPAN
style="COLOR: #000000"> constAndStatic<BR>{<BR> </SPAN><SPAN
style="COLOR: #0000ff">const</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN
style="COLOR: #000000"> i;<BR> </SPAN><SPAN
style="COLOR: #0000ff">static</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #0000ff">char</SPAN><SPAN
style="COLOR: #000000"> c;<BR> </SPAN><SPAN
style="COLOR: #0000ff">const</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #0000ff">double</SPAN><SPAN
style="COLOR: #000000"> d;<BR> </SPAN><SPAN
style="COLOR: #0000ff">static</SPAN><SPAN
style="COLOR: #000000"> </SPAN><SPAN
style="COLOR: #0000ff">void</SPAN><SPAN
style="COLOR: #000000"> TestStatic(){}<BR> </SPAN><SPAN
style="COLOR: #0000ff">void</SPAN><SPAN
style="COLOR: #000000"> TestNoStatic(){}<BR>}; </SPAN><SPAN
style="COLOR: #008000">//</SPAN><SPAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -