• <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>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評論

            C++中結(jié)構(gòu)體的字節(jié)對齊問題 ---- 轉(zhuǎn)

             

              前不久,在C++程序中碰到一個(gè)有關(guān)結(jié)構(gòu)體字節(jié)對齊的問題。

            一。問題描述

            在程序中,定義了一個(gè)結(jié)構(gòu)體,如下:
            typedef struct
            {
               char name[33];
               int ID;
               int  age;
            } PERSON;

            聲明了一個(gè)該結(jié)構(gòu)體的數(shù)組:
            PERSON peo[30];

            當(dāng)從結(jié)構(gòu)體中取出ID字段給一個(gè)int類型的局部變量賦值時(shí),卻出現(xiàn)異常.
            比如結(jié)構(gòu)體中的字段都已經(jīng)有初始值
            peo[0].ID =4;

            下面的賦值語句
            int tempID = peo[0].ID;
            卻不能正確得到數(shù)值4,tempID得到的是67108864.
            經(jīng)檢查67108864是4在高位時(shí)的數(shù)值大小.
            賦值時(shí)本來應(yīng)該是取內(nèi)存中的四個(gè)Bytes:"04 00 00 00"
            可是取值時(shí)卻是用"00 00 00 04" 的方式.
            在調(diào)試過程中,從peo[0].ID取值是正確的,得到數(shù)字4,可程序執(zhí)行上面賦值語句后:
            tempID還是得到的是67108864.

            也就是說,在調(diào)試器中取值是正確的,匯編后的程序取值卻是不正確的.
            程序在開始用了的很長一段時(shí)間并沒有出現(xiàn)這種問題,這個(gè)問題是最近才發(fā)生的.
            真是百思不得其解。還有一點(diǎn)是明確的,程序涉及到網(wǎng)絡(luò)傳輸。

            可是如果把結(jié)構(gòu)體中的字符數(shù)組大小由33改為36,一切正常了!

            原理上肯定是結(jié)構(gòu)體的位對齊問題,但為什么以前編譯使用沒出問題,現(xiàn)在編譯才發(fā)生呢?
            應(yīng)該怎么解決呢?

            二。尋找問題的原因。

            經(jīng)過CSDN社區(qū)各位老大的幫助,并且自己仔細(xì)去了解程序中的編譯條件部分,原則上理解了這問題的本質(zhì)所在。

            發(fā)現(xiàn)在網(wǎng)絡(luò)模塊中使用到了"#pram pack(1)"這樣的編譯條件,而其它模塊則沒有加入這種編譯條件。

            而CSDN中其中一個(gè)大蝦是這樣解釋的:“對齊方式是給編譯器看的,編譯器根據(jù)這個(gè)來決定內(nèi)存布局。一旦編譯成二進(jìn)制文件內(nèi)存布局就已經(jīng)確定了,如果兩段代碼對同一個(gè)結(jié)構(gòu)使用的對齊方式不同,那么就會(huì)對內(nèi)存里的值做出了不同的解釋,賦值的一方認(rèn)為char[33]占了36個(gè)字節(jié),從第37個(gè)字節(jié)填寫04 00 00 00,可是讀取的一方認(rèn)為char[33]只有33個(gè)字節(jié),那就從第34個(gè)字節(jié)處取四個(gè)字節(jié)當(dāng)作ID。”

            這次網(wǎng)友的解釋,我認(rèn)為指出了問題的本質(zhì)所在:“如果兩段代碼對同一個(gè)結(jié)構(gòu)使用的對齊方式不同,那么就會(huì)對內(nèi)存里的值做出了不同的解釋”。我們的程序給結(jié)構(gòu)體初始化部分是按VC編譯器中默認(rèn)的結(jié)構(gòu)體8字節(jié)對齊,而在網(wǎng)絡(luò)模塊中,由于使用了"#pram pack(1)",結(jié)果從結(jié)構(gòu)體中取值時(shí),編譯器認(rèn)為結(jié)構(gòu)體是按1字節(jié)對齊,最終導(dǎo)致了問題的產(chǎn)生。

            三。解決方法

            為了解決這個(gè)問題,就需要程序中所有的代碼對同一個(gè)結(jié)構(gòu)體都使用同一種對齊即可。

            會(huì)有兩種解決辦法:
            一是把網(wǎng)絡(luò)模塊中的"#pram pack(1)"去掉,結(jié)構(gòu)體都是按VC編譯器中默認(rèn)的結(jié)構(gòu)體8字節(jié)方式對齊。
            二是設(shè)置結(jié)構(gòu)體按1字節(jié)方式進(jìn)行對齊,程序所有模塊都按這種對齊方式編譯。

            設(shè)置在VC的"project"->"setting..."->"c/c++":struct member aligment改成1 Bytes.

            posted on 2008-11-05 23:30 大龍 閱讀(1963) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            7777精品伊人久久久大香线蕉 | 国产精品久久久久影院嫩草| 久久人人爽人人爽人人片AV东京热 | 久久国产欧美日韩精品| 久久99精品国产麻豆宅宅| 国产精品一区二区久久精品无码| 香港aa三级久久三级老师2021国产三级精品三级在 | 国产精品久久久久无码av| 久久久久亚洲AV成人网| 日本人妻丰满熟妇久久久久久| 91精品国产综合久久婷婷| 午夜精品久久久内射近拍高清| 国产91色综合久久免费分享| 欧美大战日韩91综合一区婷婷久久青草| 午夜天堂精品久久久久| 人妻精品久久久久中文字幕| 精品亚洲综合久久中文字幕| 久久国语露脸国产精品电影| 狠狠色综合久久久久尤物| 精品久久久久久久无码 | 久久A级毛片免费观看| 久久婷婷五月综合色99啪ak| 女人香蕉久久**毛片精品| 久久WWW免费人成一看片| 久久久久亚洲AV综合波多野结衣 | 精品久久久久中文字| 97久久天天综合色天天综合色hd| 久久精品国产男包| 久久久艹| 亚洲国产精品成人AV无码久久综合影院 | 国产aⅴ激情无码久久| 国产精品亚洲综合久久| 久久五月精品中文字幕| 久久无码人妻精品一区二区三区 | 久久精品九九亚洲精品| 一本久道久久综合狠狠爱| 久久乐国产综合亚洲精品| 久久亚洲AV成人无码软件| 伊人久久综合无码成人网| 久久综合亚洲鲁鲁五月天| 亚洲人成网亚洲欧洲无码久久|