• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            攀升·Uranus


            Something Different,Something New
            數據加載中……

            結構體對齊那點事 熟練c/c++(四)

                      剛剛完成一個文件的遷移程序,其中遇到了結構體對齊的問題,所以拿出來說說,與各位博友們分享。

            我的程序很簡單,就是把之前通過一個結構體fwrite到文件A里的內容讀出,然后轉給另一個結構體保存。程序是簡單,但我擔心的是之前結構體fwrite到文件A的程序對齊結構體規則是怎樣的?一定要知道它嗎? 當然了,如果那個程序結構體是按照1對齊寫入的,我的程序結構體是按照4對齊讀入,那不就糟了!

                  這里我引入結構體對齊的概念,也可以說是內存對齊了。為什么要內存對齊呢,就是方便CPU尋址了,具體原因大家要參考計算機體系結構了。先看一個內存對齊的例子:

                  struct example1{

                       char a;

                       double b;

                       long l;

            };

                  struct example2{

                       char a;

                       long l;

                       double b;

            };

            大家算算結構體大小,初次接觸的博友可能對答案有點驚訝,VC編譯, sizeof后結果分別是:2416 同樣是的結構體,成員換了順序,大小就不同了。其實內存對齊有個規則,只要知道了,就OK。那么以下5點是關鍵

            1.          內存對齊與編譯器設置有關,首先要搞清編譯器這個默認值是多少

            2.          如果不想編譯器默認的話,可以通過#pragma pack(n)來指定按照n對齊

            3.          每個結構體變量對齊,如果對齊參數n(編譯器默認或者通過pragma指定)大于該變量所占字節數(m),那么就按照m對齊,內存偏移后的地址是m的倍數,否則是按照n對齊,內存偏移后的地址是n的倍數。也就是最小化長度規則

            4.          結構體總大小: 對齊后的長度必須是成員中最大的對齊參數的整數倍。最大對齊參數是從第三步得到的。

            5.          補充:如果結構體A中還要結構體B,那么B的對齊方式是選它里面最長的成員的對齊方式

            所以計算結構體大小要走三步,首先確定是當前程序按照幾對齊(參照12),接著計算每個結構體變量的大小和偏移(參照35),最后計算結構體總大小(參照4)。

                  先算算example1吧,假設編譯器是以16對齊的

                  1.確定按照幾對齊: 16;

                  2.確定每個成員的偏移:a 占一個字節,16>1, 按照1對齊,起始位置00%1 = 0,那么a就存在0位置;b8個字節,16>8,按照8對齊,起始位置就不能是1了,因為要按照8對齊,所以最近的偏移起始位置是8 8%8 =0, 那么b就存在位置8-15的位置;l4個字節,16>4,按照4對齊,起始位置16 16%4=0,那么l就存在位置16-19的位置。所以結構體從019一共占用20個字節

                  3.結構體總大小:成員中最大的對齊參數是b8對齊,所以208!=0, 24剛好。

                  真的很搞!同理計算example2應該是16

                 再舉個結構體嵌套的例子吧,

            #pragma pack(push)

            #pragma pack(8)

            struct test1{

                  int a;

                  char b;

                  int c[20]

            long l;

            } ;

            struct test2{

                  char a1;

                  char a2;

                  struct test1 t1;

                  double b1;

            }

            #pragma pack(pop)

            先計算test1, 8對齊,a占用0-3b占用4c占用887l占用8891,一共92個字節。成員中最大的對齊參數是int92%4=0;

            再計算test2, a1z占用0a2占用1t1呢,4 % 4 (test1里面最長的成員的對齊方式) = 0, 4-95b196103;一共104個字節,成員中最大的對齊參數是double104%8=0; 所以是104.


                  那關于我文章開頭提到的那個文件轉換,我現在只要知道原始程序是按照什么對齊的,然后在新程序中指定按照幾對齊就可以了,哈哈!            
                  
                  擠時間寫的,
            有的地方有遺漏,請各位指正!

            posted on 2009-01-06 23:39 攀升 閱讀(8860) 評論(9)  編輯 收藏 引用 所屬分類: C/C++

            評論

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            恩. 很有道理
            2009-01-07 11:13 | li_young

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            在gcc下example1和example2都是16
            2009-01-07 12:53 | ronliu

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            在gcc下example1和example2都是16 中默認字節對齊為4 所以都是16
            2009-01-07 16:57 | feosun

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            @ronliu
            博友feosun告訴了你答案
            所以為了防止不同編譯器對齊不一樣,我建議在代碼里面指定對齊參數
            #pragma pack(n)
            2009-01-07 18:14 | 攀升

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            內存對齊一直是很熱的話題啊。。呵呵。。。
            2009-01-08 08:38 | guest

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            有個地方沒太看懂
            就是嵌套結構體時,如何決定嵌套結構體的首地址?即文中"t1呢,92%2!=0, 2-92"這一段,不是說考慮結構體大小時,應該為其成員的最大值么?
            2009-08-31 10:54 | 游客

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            能否把我給你的評論(最前面的兩條中有)刪掉,我的留言中使用了郵件地址,收到了無數的垃圾郵件,煩都煩死了。如果可以,真的不勝感激
            2009-10-16 22:09 | 你好!

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            @你好!
            我幫你處理了,哈哈
            2010-01-14 23:12 | 攀升

            # re: 結構體對齊那點事 熟練c/c++(四)   回復  更多評論   

            @游客
            >有個地方沒太看懂
            >就是嵌套結構體時,如何決定嵌套結構體的首地址?即文中"t1呢,92%2!>=0, 2-92"這一段,不是說考慮結構體大小時,應該為其成員的最大值么?

            謝謝你的提醒,我改好了,呵呵
            2010-01-14 23:24 | 攀升
            九九热久久免费视频| 久久午夜电影网| 狠狠色噜噜色狠狠狠综合久久| 色综合合久久天天给综看| 伊人久久国产免费观看视频| 狼狼综合久久久久综合网| 久久国产精品成人免费| 久久综合久久综合亚洲| 97r久久精品国产99国产精| 久久青青草原精品国产软件 | 久久综合综合久久97色| 久久久久亚洲爆乳少妇无| 浪潮AV色综合久久天堂| 久久久亚洲精品蜜桃臀| 99久久精品国产高清一区二区| 久久精品国产色蜜蜜麻豆| 国产麻豆精品久久一二三| 久久人人爽人人爽AV片| 久久久精品免费国产四虎| 久久久久久伊人高潮影院| 精品久久久久久久中文字幕| 久久99精品久久久久久久久久| 欧美色综合久久久久久| 国内精品久久久久影院网站 | 久久婷婷午色综合夜啪| 国产亚州精品女人久久久久久 | 久久久噜噜噜久久熟女AA片| 无码精品久久一区二区三区| 欧美综合天天夜夜久久| 久久精品中文无码资源站| 久久久午夜精品| 亚洲精品国产第一综合99久久| 久久综合一区二区无码| 成人精品一区二区久久| 伊人久久综合热线大杳蕉下载| 国产精品久久永久免费| 国产精品久久久久久久久鸭| 91精品国产综合久久久久久| 国产精品岛国久久久久| 亚洲嫩草影院久久精品| 久久久久国产一级毛片高清板|