beiyu95的专栏

关注测试技术的个人空间

北玉ID:beiyu95
10573次访问,排名9939(-1)好友0人,关注者4
beiyu95的文章
原创 9 篇
翻译 0 篇
转载 11 篇
评论 24 篇
beiyu95的公告
本人Blog上可能收藏和参考了一些有知识产权的东西,如果你认为我的行为侵犯了您的知识产权或其他权益,请联系本人,本人即刻修改。联系方式:beiyu95@163.com
最近评论
文章分类
收藏
    相册
    精彩无限
    技术站点
    www.theseverside.com
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    转载 sizeof and alignment收藏

    新一篇: Basic concepts of pragma pack and alignment  | 旧一篇: 从java中调用UNIX中的shell的脚本的方法

     

    C++中的尺寸

    1. sizeof:返回类型的尺寸

     每个类型在编译时都会决定自己的实例需要多少字节。在编译后,该类型的所有对象占有的空间是一样的,不会发生变化。因此,我们可以用sizeof来计算一个类型或者该类型的某个实例来得到尺寸信息。下面的代码是等价的


    int iVal;
    //sizeof type
    sizeof(int)
    //sizeof instance
    sizeof(iVal)

    无论我们用iVal还是int,上面的表达式都会返回int类型的尺寸(当然如前所说,iVal的尺寸和其类型尺寸永远是一样的)。

    不熟悉sizeof的朋友往往会在处理指针时弄错概念。考虑下面代码:

    int iArray[10];
    int sizeofArray=sizeof(iArray);

    int * p= new int[10];
    int sizeofPointer = sizeof(p);

    在很多人心目中,指针和数组是等价的,但是事实严格起来并不如此。上面的代码就会返回不同的结果。

    对 于iArray,它的类型是int[10],是一个数组,sizeof计算其尺寸时,知道它包含10个元素,每个元素都时个整型,因此返回40。而对于 p,它的类型是int*,指针的尺寸永远是4,因此结果就是4。sizeof不会也不可能知道p实际指向10个元素的数组。

    出现这个问题的 原因有两个:1. sizeof是在编译时计算的,而new int[10]指向的数组是在运行时创建的,也就是说当sizeof(p)计算时,系统还不知道p会指向多少个int元素,自然也不可能知道它指向的数组 占有多少字节。2. sizeof计算的是p自己的类型所占据的空间,而不是p指向的对象所占据的空间,可以说,p自己占据4个字节,而p指向的空间占40字节。

    在这种概念下,我们是不是可以通过sizeof(*p)来得到40呢?很不幸,不行,原因是p的类型是int*,*p的类型是int,因此无法得到其是一个数组的事实。

    实际上,这个尺寸信息是个运行时数据,作为C/C++语言而言,是无从知道这个信息的(因为C/C++指针不包含这种信息),要得到它,唯一的办法是指望操作系统在运行时中提供。在VC中,我们可以通过_msize得到。

    2. 对齐问题

    我 们在访问内存时,如果地址是按4字节对齐,则访问效率会高很多。这个问题的原因在于访问内存的硬件电路。一般情况下,地址总线总是按照对齐后的地址来访 问。例如你想得到0x00000001开始的4字节内容,系统首先需要以0x00000000读4字节,然后从中取得3字节,然后在用 0x00000004作为开始地址,获得下一个四字节,在从中得到第一个字节,两次组合出你想得到的内容。但是如果地址一开始就是对齐到 0x00000000,则系统只要一次读写即可。

    为了性能考虑,编译器会对结构进行对齐处理。考虑下面的结构

     

    struct aStruct
    {
                   
    char cValue;
                   
    int    iValue;
    }
    ;

     

    直观的讲,这个结构的尺寸是sizeof(char)+sizeof(int)=6,但是在实际编译下,这个结构尺寸缺省是8,因为第二个域ivalue会被对齐到第四个字节。

    在VC中,我们可以用pack预处理指令来禁止对齐调整。例如,下面代码将使得结构尺寸更加紧凑,不会出现对齐到4字节问题:

     

    #pragma pack(1)
    struct aStruct{
         
    char cValue;
        
    int     iValue;
    }
    ;
    #pragma pack()

    对于这个pack指令的含义,大家可以查询MSDN。请注意:除非你觉得必须这样,不要轻易做这样的调整,因为这将降低程序性能。目前比较常见的用法是:1. 这个结构需要被直接写入文件 2. 这个结构需要通过网络传给其他程序。

    注意:字节对齐是编译时决定的,一旦决定不会再改变,因此即使有对齐的因素在,也不会出现一个结构在运行时尺寸发生变化的情况出现。



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2210462

    发表于 @ 2008年04月06日 10:35:00|评论(loading...)|编辑

    新一篇: Basic concepts of pragma pack and alignment  | 旧一篇: 从java中调用UNIX中的shell的脚本的方法

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © beiyu95