• <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 攀升 閱讀(8858) 評論(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 | 攀升
            久久中文字幕视频、最近更新| 国产精品嫩草影院久久| 久久久精品视频免费观看| 精品久久久久久| 97精品国产91久久久久久| 精品乱码久久久久久久| 无码专区久久综合久中文字幕| 一日本道伊人久久综合影| 国产精品久久久久久久久久影院| 久久中文字幕无码专区| 久久精品无码一区二区WWW| 欧美伊人久久大香线蕉综合| 波多野结衣AV无码久久一区| 久久夜色精品国产网站| 欧美777精品久久久久网| 国产精品嫩草影院久久| 亚洲国产成人精品91久久久| 亚洲中文字幕无码一久久区| 精品蜜臀久久久久99网站| 岛国搬运www久久| 欧美一级久久久久久久大| 97久久国产露脸精品国产| 青青热久久综合网伊人| 久久久这里有精品中文字幕| 亚洲欧美日韩久久精品第一区| 久久国产亚洲精品麻豆| 性做久久久久久久久老女人| 国产午夜免费高清久久影院| 久久久久亚洲AV成人网人人网站| 欧美亚洲国产精品久久| 国产叼嘿久久精品久久| 国产亚洲精久久久久久无码77777 国产亚洲精品久久久久秋霞 | 亚洲精品乱码久久久久66| 久久国产免费观看精品3| 久久久久久极精品久久久 | 国产成人精品久久一区二区三区av | 久久伊人五月丁香狠狠色| 久久亚洲精品视频| 亚洲va久久久噜噜噜久久男同 | 国产精品久久成人影院| 18禁黄久久久AAA片|