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

            最新評(píng)論

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

             

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

            一。問(wèn)題描述

            在程序中,定義了一個(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;

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

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

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

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

            二。尋找問(wèn)題的原因。

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

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

            而CSDN中其中一個(gè)大蝦是這樣解釋的:“對(duì)齊方式是給編譯器看的,編譯器根據(jù)這個(gè)來(lái)決定內(nèi)存布局。一旦編譯成二進(jìn)制文件內(nèi)存布局就已經(jīng)確定了,如果兩段代碼對(duì)同一個(gè)結(jié)構(gòu)使用的對(duì)齊方式不同,那么就會(huì)對(duì)內(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)為指出了問(wèn)題的本質(zhì)所在:“如果兩段代碼對(duì)同一個(gè)結(jié)構(gòu)使用的對(duì)齊方式不同,那么就會(huì)對(duì)內(nèi)存里的值做出了不同的解釋”。我們的程序給結(jié)構(gòu)體初始化部分是按VC編譯器中默認(rèn)的結(jié)構(gòu)體8字節(jié)對(duì)齊,而在網(wǎng)絡(luò)模塊中,由于使用了"#pram pack(1)",結(jié)果從結(jié)構(gòu)體中取值時(shí),編譯器認(rèn)為結(jié)構(gòu)體是按1字節(jié)對(duì)齊,最終導(dǎo)致了問(wèn)題的產(chǎn)生。

            三。解決方法

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

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

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

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


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


            欧美色综合久久久久久| 国产91色综合久久免费| 伊人色综合久久| 久久国产亚洲精品麻豆| 97久久久久人妻精品专区| av无码久久久久不卡免费网站 | 国产成人久久久精品二区三区| 久久影院综合精品| 久久人人爽人人爽人人AV东京热| 无码任你躁久久久久久老妇App| 亚洲人AV永久一区二区三区久久| 欧美日韩中文字幕久久久不卡| 久久这里有精品视频| 久久伊人中文无码| 精品伊人久久大线蕉色首页| 亚洲色欲久久久综合网东京热| 日产精品久久久久久久性色| 日韩AV无码久久一区二区| …久久精品99久久香蕉国产 | 久久精品人人做人人爽电影 | 久久婷婷综合中文字幕| 亚洲国产精品热久久| 亚洲国产精品综合久久网络 | 99久久www免费人成精品| 国内精品久久久久久久影视麻豆| 久久香蕉国产线看观看猫咪?v| 久久精品国产男包| 国产精品美女久久久久久2018| 久久www免费人成精品香蕉| 国产精品99久久久精品无码| 69国产成人综合久久精品| 国产综合精品久久亚洲| 亚洲精品乱码久久久久久按摩| 久久综合九色综合欧美狠狠| 理论片午午伦夜理片久久| 国产成人久久AV免费| 午夜视频久久久久一区| 青青国产成人久久91网| 亚洲精品无码久久久影院相关影片 | 久久久久久国产a免费观看黄色大片| 久久婷婷五月综合97色|