计算机中c语言字节对齐自然对齐问题

博客访问: 18828
博文数量: 32
博客积分: 0
博客等级: 民兵
技术积分: 370
注册时间:
路漫漫其修远兮,吾将上下而求索
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
发布时间: 10:43:00
&p&struct& {}&/p&&p&32为的x86,window下VC下sizeof(node)的值为1,而linux的gcc下值为0;&/p&&hr /&&p&一、WINDOWS下(VC--其实GCC和其原理基本一样,象这种问题,一般要查具体的编译器设置)字节对齐的规则:&/p&&p&1、一般设置的对齐方式为1,2,4字节对齐方式,VC一般默认为4字节(最大为8字.........
阅读(225) | 评论(0) | 转发(0)
发布时间: 12:33:26
阅读(340) | 评论(0) | 转发(0)
发布时间: 11:12:38
阅读(393) | 评论(0) | 转发(0)
发布时间: 17:25:12
编译器自带宏定义,可以查看时间,文件位置......
阅读(523) | 评论(0) | 转发(0)
给主人留下些什么吧!~~
请登录后留言。编程基础:关于编程时的字节对齐问题【邓文武吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:45贴子:
编程基础:关于编程时的字节对齐问题
很多初学编程的人在对结构体使用时的返回值即实际占用内存与理想占用内存的差异可能会感到困惑,为什么sizeof的返回值大于等于结构体中各成员占用字节数之和呢?这实际上涉及到计算机系统中字节对齐的问题。1. 字节对齐的概念字节对齐跟数据在内存中的位置有关。如果一个变量的正好位于它长度的整数倍,他就被称做自然对齐。比如在32位下,假设一个的地址为0x,那它就是自然对齐的。附图:冥王星-一个时代过去了,但我们的脚步永远不会停下直到我们死去
贴吧热议榜
使用签名档&&
保存至快速回贴C语言字节对齐问题详解
一、何谓字节对齐?
现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲,似乎对任何类型变量的访问都可以从任何地址开始,但实际情况是在访问特定变量的时候,经常在特定的内存地址访问,而不是顺序的一个接一个的排放。为了使CPU能够对变量进行快速访问,变量的起始地址应该具有某些特性,即所谓的&字节对齐&。比如4字节的int型,其起始地址应该位于4字节的边界上,即起始地址能够被4整除。
在C语言中,结构体是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构体、联合等)的数据单元。在结构体中,编译器为结构体的每个成员按其自然边界(alignment)分配空间,各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。
二、字节对齐的作用和原因
各个硬件平台对存储空间的处理上有很大的不同。一些平台(例如sparc对字节对齐非常严格)对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台(例如x86)每次读都是从偶地址开始,如果一个int型(假设为32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出;而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该int型数据。后者显然在读取效率上会下降很多,但存储空间上可能比前者更紧凑,这也是空间和时间的取舍。
三、字节对齐原则
编译器是按照什么样的原则进行对齐的?在我们继续分析具体字节对齐问题之前,先让我们看几个重要的基本概念:
1.数据类型自身的对齐值:在32位x86机器上,对于char型数据,其自身对齐值为1字节;对于short型,其自身对齐为2字节;对于 int,long, float类型,其自身对齐值为4字节;
对于long long,double类型为8字节;对于基本类型的指针类型(其本质是 unsigned long型),其自身对齐为4字节。
2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:#pragma pack (value)时的指定对齐值value。
4.编译器默认对齐值:一般与CPU字长位数相同,在32位机器上为4字节,64位机器上为8字节。未指定对齐值时,编译器使用默认对齐值。
5.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
有了这些值,我们就可以很方便的来讨论具体数据结构的成员和其自身的对齐方式。有效对齐值N是最终用来决定数据存放地址方式的值,最重要。有效对齐N,就 是表示&对齐在N上&,也就是说该数据的&存放起始地址%N=0&.而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是 数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整 数倍。
四、字节对齐举例分析
根据字节对齐原则,结合下面例子理解,就明白了。
例子分析:
分析例子B;
struct B {
假设B从地址空间0x0000开始排放。该例子中没有定义指定对齐值,在笔者环境下,该值默认为4。第一个成员变量b的自身对齐值是1,比指定或者默认指 定对齐值4小,所以其有效对齐值为1,所以其存放地址0x0000符合0x.第二个成员变量a,其自身对齐值为4,所以有效对齐值也为 4,所以只能存放在起始地址为0x7这四个连续的字节空间中,复核0x,且紧靠第一个变量。第三个变量c,自身对齐 值为2,所以有效对齐值也是2,可以存放在0x9这两个字节空间中,符合0x。所以从0x9存 放的都是B内容。再看数据结构B的自身对齐值为其变量中最大对齐值(这里是b)所以就是4,所以结构体的有效对齐值也是4。根据结构体圆整的要求, 0x0=10字节,(10+2)%4=0。所以0x0000A到0x000B也为结构体B所占用。故B从0xB 共有12个字节,sizeof(struct B)=12;
同理,分析上面例子C:
#pragma pack (2) /*指定按2字节对齐*/
struct C {
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
第一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x;第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x3、0x5四个连续 字节中,符合0x。第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序存放
在0x7中,符合0x。所以从0x07共八字节存放的是C的变量。又C的自身对齐值为4,所以 C的有效对齐值为2。又8%2=0,C只占用0x7的八个字节。所以sizeof(struct C)=8.
有 了以上的解释,相信你对C语言的字节对齐概念应该有了清楚的认识了吧。在网络程序中,掌握这个概念可是很重要的喔,在不同平台之间(比如在Windows 和之间)传递2进制流(比如结构体),那么在这两个平台间必须要定义相同的对齐方式,还要注意字节大端和小端的问题,否则会莫名其妙地出现一些诡异的错误,可是很难排查的哦^_^。
六、附源代码
[cpp] view plaincopyprint?
/****************************************************************************** Copyright by code007, All rights reserved!
Filename : structsize.c Author : Javacode007
Version : 1.0
Description : 结构体类型大小测试 ******************************************************************************/
struct A {
#pragma pack(1) /*指定按1字节对齐*/ struct PA
}; #pragma pack() /*取消指定对齐,恢复缺省对齐*/
struct B {
#pragma pack(2) /*指定按2字节对齐*/
struct PB {
#pragma pack() /*取消指定对齐,恢复缺省对齐*/
int main() {
struct A stA; struct PA stPA;
struct B stB; struct PB stPB;
printf(&sizeof(A) = %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stA), &stA.c, &stA.s, &stA.i); printf(&sizeof(PA) = %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stPA), &stPA.c, &stPA.s, &stPA.i);
printf(&sizeof(B) = %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stB), &stB.c, &stB.s, &stB.i); printf(&sizeof(PB) = %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stPB), &stPB.c, &stPB.s, &stPB.i);
/******************************************************************************
Copyright by Javacode007, All rights reserved!
: structsize.c
: Javacode007
Description : 结构体类型大小测试
******************************************************************************/
#pragma pack(1) /*指定按1字节对齐*/
#pragma pack()
/*取消指定对齐,恢复缺省对齐*/
#pragma pack(2) /*指定按2字节对齐*/
#pragma pack()
/*取消指定对齐,恢复缺省对齐*/
int main()
struct A stA;
struct PA stPA;
struct B stB;
struct PB stPB;
printf(&sizeof(A)
= %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stA), &stA.c, &stA.s, &stA.i);
printf(&sizeof(PA) = %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stPA), &stPA.c, &stPA.s, &stPA.i);
printf(&sizeof(B)
= %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stB), &stB.c, &stB.s, &stB.i);
printf(&sizeof(PB) = %d, &c = %p, &s = %p, &i = %p\r\n&, sizeof(stPB), &stPB.c, &stPB.s, &stPB.i);
输出结果:结构体字节对齐问题_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
结构体字节对齐问题
&&结构体字节对齐问题
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢用户名:李云
文章数:187
评论数:1756
访问量:1394377
注册日期:
阅读量:1297
阅读量:3317
阅读量:456980
阅读量:1141634
51CTO推荐博文
&&& 字节对齐(alignment)是CPU在性能方面所面临的一个非常重要的问题。有些处理器能自动的处理不对齐数据的访问(对字节对齐要求不严格),但是,有些处理器却无法处理(对字节对齐要求很严格)。当处理器无法处理对齐问题时,其将引发一个异常(exception),当然从程序的角度来说就是出错(crash)。
对于C程序员,大部分情况下我们并不考虑字节对齐问题,这并不是说我们不需要考虑,而是因为碰到这种问题的情况很少。一方面要在特定的处理器上,而另一方面和我们写的程序也有关系,只有两个条件同时满足时问题才会出现。因此,结果给我们的感觉是“字节对齐与我无关”。
本文通过对一小段简单的代码在不同处理器上的运行结果引出对字节对齐问题的关注,同时对其原因进行了分析。
...请下载附件阅读全文。本文出自 “” 博客,请务必保留此出处
了这篇文章
附件下载:  
类别:┆阅读(0)┆评论(0)
请输入验证码:

我要回帖

更多关于 字节对齐 的文章

 

随机推荐