📄 c struct 中字节对齐问题 - ehui928的专栏 - csdnblog.htm
字号:
<P>始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方</P>
<P>,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总</P>
<P>的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的</P>
<P>类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整</P>
<P>个结构的大小为:sizeof(MyStruct)=8+1+ 3+4=16,其中有3个字节是VC自动填充的,没有</P>
<P>放任何有意义的东西。 <BR>下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况</P>
<P>: <BR>struct MyStruct <BR>{ <BR>char dda; <BR>double dda1; <BR>int
type <BR>}; <BR>这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)为24。结</P>
<P>合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。(简单说</P>
<P>明) <BR>struct MyStruct <BR>{ <BR> char dda;//偏移量为0,满足对齐方式,dda占用1个字节;
<BR>double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8 <BR>
//的倍数,需要补足7个字节才能使偏移量变为8(满足对齐 <BR> //方式),因此VC自动填充7个字节,dda1存放在偏移量为8 <BR>
//的地址上,它占用8个字节。 <BR>int type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍 <BR>
//数,满足int的对齐方式,所以不需要VC自动填充,type存 <BR> //放在偏移量为16的地址上,它占用4个字节。
<BR>};//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构 <BR>
//的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof <BR> //(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为
<BR> //sizeof(double)=8的倍数。
<BR>所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节</P>
<P>是VC自动填充的,没有放任何有意义的东西。<BR>VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻</P>
<P>烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。<BR>VC 中提供了#pragma
pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存</P>
<P>放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏</P>
<P>移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移</P>
<P>量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况</P>
<P>:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的</P>
<P>变量占用的空间数的倍数; <BR><BR>否则必须为n的倍数。下面举例说明其用法。 <BR>#pragma pack(push)
//保存对齐状态 <BR>#pragma pack(4)//设定为4字节对齐 <BR>struct test <BR>{ <BR> char
m1; <BR> double m4; <BR> int m3; <BR>}; <BR>#pragma pack(pop)//恢复对齐状态
</P>
<P>以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足</P>
<P>我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为 m4分配空间,这时</P>
<P>其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大</P>
<P>于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用</P>
<P>4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如</P>
<P>果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。</P>
<P>(请读者自己分析) <BR><BR>2、 sizeof用法总结
<BR><BR>在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的</P>
<P>参数对sizeof的用法做个总结。 <BR>A.
参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种情</P>
<P>况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位</P>
<P>系统中占2个字节,在32位系统中占4个字节。 <BR>B. 参数为数组或指针。下面举例说明. <BR>int a[50];
//sizeof(a)=4*50=200; 求数组所占的空间大小 <BR>int *a=new int[50];// sizeof(a)=4;
a为一个指针,sizeof(a)是求指针 <BR> //的大小,在32位系统中,当然是占4个字节。 <BR>C.
参数为结构或类。Sizeof应用在类和结构的处理情况是相同的。但有两点需要注</P>
<P>意,第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存</P>
<P>储位置与结构或者类的实例地址无关。 <BR>第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一
<BR>个实例在内存中都有唯一的地址。 <BR>下面举例说明, <BR>Class Test{int a;static double
c};//sizeof(Test)=4. <BR>Test *s;//sizeof(s)=4,s为一个指针。 <BR>Class test1{
};//sizeof(test1)=1; <BR>D. 参数为其他。下面举例说明。 <BR> int func(char s[5]); <BR> {
<BR> cout< //数的参数在传递的时候系统处理为一个指针,所 <BR> //以sizeof(s)实际上为求指针的大小。 <BR>
return 1; <BR>} <BR>sizeof(func(“1234”))=4//因为func的返回类型为int,所以相当于 <BR>
//求sizeof(int). <BR>以上为sizeof的基本用法,在实际的使用中要注意分析VC的分配变量的分配策略,这</P>
<P>样的话可以避免一些错误 </P>
<P> </P><BR><BR>
<P id=TBPingURL>Trackback:
http://tb.blog.csdn.net/TrackBack.aspx?PostId=546391</P><BR></DIV>
<DIV class=postFoot>
<SCRIPT src=""></SCRIPT>
[<A title=功能强大的网络收藏夹,一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐
href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏到我的网摘</A>]
ehui928发表于 2005年12月07日 20:54:00 </DIV></DIV><LINK
href="http://blog.csdn.net/ehui928/Services/Pingback.aspx" rel=pingback><!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><rdf:Descriptionrdf:about="http://blog.csdn.net/ehui928/archive/2005/12/07/546391.aspx"dc:identifier="http://blog.csdn.net/ehui928/archive/2005/12/07/546391.aspx"dc:title="C struct 中字节对齐问题"trackback:ping="http://tb.blog.csdn.net/TrackBack.aspx?PostId=546391" /></rdf:RDF>-->
<SCRIPT>function hide(){showComment();}</SCRIPT>
<BR><BR><BR>
<DIV class=post id=csdn_zhaig_ad_yahoo></DIV>
<SCRIPT type=text/javascript>document.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");</SCRIPT>
<SPAN class=PreAndNext id=viewpost.ascx_PreviousAndNextEntriesDown>
<DIV align=center><A
href="http://blog.csdn.net/ehui928/archive/2005/12/10/548671.aspx">上一篇: linux下代码阅读环境的快速建立--lxr+glimpse</A> | <A
href="http://blog.csdn.net/ehui928/archive/2005/12/07/546390.aspx">下一篇: C/C++语言void及void指针深层探索(转载)</A></DIV></SPAN><SPAN
id=Anthem_Comments.ascx_ltlComments__><SPAN id=Comments.ascx_ltlComments><BR>
<DIV id=comments>
<H3></H3>没有评论。 </DIV></SPAN></SPAN>
<SCRIPT language=javascript>
ad_width=468;
ad_height=60;
adcss=2;
unionuser=19;
ad_type='j';
count=5;
</SCRIPT>
<SCRIPT language=javascript
src="C struct 中字节对齐问题 - ehui928的专栏 - CSDNBlog.files/showads.js"
type=text/javascript></SCRIPT>
<SCRIPT language=javascript
src="C struct 中字节对齐问题 - ehui928的专栏 - CSDNBlog.files/showgm.js"
type=text/javascript></SCRIPT>
<DIV id=commentform>
<DIV id=Anthem_PostComment.ascx_CommentUpdatePanel__>
<DIV id=PostComment.ascx_CommentUpdatePanel>
<TABLE cellSpacing=1 cellPadding=1 border=0>
<TBODY>
<TR>
<TD width=75>大名</TD>
<TD><INPUT id=PostComment.ascx_tbName style="WIDTH: 300px" disabled
maxLength=32 size=40 value=lwei_cxdn2007 name=PostComment.ascx:tbName></TD>
<TD><SPAN id=PostComment.ascx_RequiredFieldValidator2
style="VISIBILITY: hidden; COLOR: red" initialvalue=""
evaluationfunction="RequiredFieldValidatorEvaluateIsValid"
errormessage="请输入名字"
controltovalidate="PostComment.ascx_tbName">请输入名字</SPAN></TD></TR>
<TR>
<TD>网址</TD>
<TD><INPUT id=PostComment.ascx_tbUrl style="WIDTH: 300px" maxLength=256
size=40 name=PostComment.ascx:tbUrl></TD>
<TD></TD></TR>
<TR>
<TD colSpan=3>评论 <SPAN id=PostComment.ascx_RequiredFieldValidator3
style="VISIBILITY: hidden; COLOR: red" initialvalue=""
evaluationfunction="RequiredFieldValidatorEvaluateIsValid"
errormessage="请输入评论"
controltovalidate="PostComment.ascx_tbComment">请输入评论</SPAN><BR><TEXTAREA id=PostComment.ascx_tbComment style="WIDTH: 400px; HEIGHT: 193px" name=PostComment.ascx:tbComment rows=10 cols=50></TEXTAREA></TD></TR>
<TR>
<TD><SPAN id=Anthem_PostComment.ascx_btnSubmit__><INPUT language=javascript class=Button id=PostComment.ascx_btnSubmit onclick="javascript:Anthem_FireCallBackEvent(this,event,'PostComment.ascx:btnSubmit','',true,'','','正在处理...',false,null,null,null,true,true);return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("PostComment.ascx:btnSubmit", "", true, "", "", false, false))" type=submit value=提交 name=PostComment.ascx:btnSubmit></SPAN></TD>
<TD colSpan=2><SPAN id=PostComment.ascx_Message
style="COLOR: red"></SPAN></TD></TR></TBODY></TABLE></DIV></DIV></DIV></DIV>
<P id=footer>Powered by: <BR><A id=Footer1_Hyperlink2
href="http://scottwater.com/blog" name=Hyperlink1><IMG
src="C struct 中字节对齐问题 - ehui928的专栏 - CSDNBlog.files/100x30_Logo.gif"
border=0></A> <A id=Footer1_Hyperlink3 href="http://asp.net/"
name=Hyperlink1><IMG
src="C struct 中字节对齐问题 - ehui928的专栏 - CSDNBlog.files/PoweredByAsp.Net.gif"
border=0></A> <BR>Copyright © ehui928 </P>
<SCRIPT
src="C struct 中字节对齐问题 - ehui928的专栏 - CSDNBlog.files/counter.js"></SCRIPT>
<SCRIPT type=text/javascript>
<!--
var Page_Validators = new Array(document.getElementById("PostComment.ascx_RequiredFieldValidator2"), document.getElementById("PostComment.ascx_RequiredFieldValidator3"));
// -->
</SCRIPT>
<INPUT id=__EVENTVALIDATION type=hidden
value=/wEWBQL+raDpAgKqtOi0AwLAsuLbDAKi687YCQKG6K6RCAHKss+LIey8yvaml2ED1YgW6ieu
name=__EVENTVALIDATION>
<SCRIPT type=text/javascript>
<!--
var Page_ValidationActive = false;
if (typeof(ValidatorOnLoad) == "function") {
ValidatorOnLoad();
}
function ValidatorOnSubmit() {
if (Page_ValidationActive) {
return ValidatorCommonOnSubmit();
}
else {
return true;
}
}
// -->
</SCRIPT>
</FORM>
<SCRIPT language=javascript type=text/javascript>
<!--
try
{
hide();
}
catch(e){}
//-->
</SCRIPT>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -