這酷兄逛C_and_Cpp板轉來的問題.. 花了點時間玩了一下 這之前好像有印象會有這種情形 但是沒真的去試過.. 在Linux下寫ㄧ個 test.c 的程式 定義ㄧ個t的struct裡面各有char,short,long,int四種資料型態 然後把struct的size print出來 然後用gcc去compile 但用sizeof所計算出來的t struct卻是12 =\= (1+2+4+4) 那麼多出來的1個byte 是誰佔去了?? 所以程式下面把這個struct的記憶體位置print出來 轉成方便了解ㄧ點的圖 看到沒 char佔 1 byte沒錯 但是他與下一個short所離的位址卻是2 byte 再來我把同樣的function 放到ARM的CPU上跑 當然也是Linux 只是用arm-linux-gcc做compile 看來跟在PC上執行是同樣的結果 只是在這ARM-Linux上跑 struct的記憶體用的位址都是固定的 在PC上跑記憶體位址會變動 再來把他放到8051上跑 用Keil C 來compile (這我天天在玩的機器阿 @@) char佔 1 byte short佔 2 byte long佔 4 byte int佔 2 byte 整個struct佔9 byte int的define跟gcc不一樣 不過看起來Keil C沒有偷佔用記憶體 但是我下面print記憶體位址的寫的有問題 抓不到確切的記憶體位址 所以其實也是有可能是錯誤的 算式或許正確 但是記憶體裡配置的方式可能又另外一回事 這... 下次研究研究 繼續把平台轉回到PC上 但是這次把struct做些修改 變成 typedef struct _test { char ch0; char ch1; int in; short sh; }test; 結果又更不一樣了 整個被偷吃了4 byte gcc到底搞了什麼鬼呢? WiKi是有解答的 http://en.wikipedia.org/wiki/Data_structure_alignment 看到最後面的Example 就是gcc做了padding的動作 struct變成了 typedef struct _test { char ch0; char ch1; char padding0[2]; int in; short sh; char padding1[2]; }test; padding的部份就是我們看起來被吃掉的記憶體 所以要避免這些padding的部份 對我來說最爛方式就是自己算好 例如改成 typedef struct _test { char ch0; char ch1; short sh; int in; }test; 這樣去執行 就不會有被偷吃的地方了 但是這樣是最基本的人工硬幹方式自己把padding處理掉 wiki會紅不是沒有道理的 後面還有教學 用#pragma來更改packing struct的size成1 在struct的前後加上 #pragma pack(push) /* push current alignment to stack */ #pragma pack(1) /* set alignment to 1 byte boundary */ typedef struct _test { char ch0; char ch1; int in; short sh; }test; #pragma pack(pop) /* restore original alignment from stack */ 再執行 padding的部份就不見了 記憶體位址也堆疊起來了 看wiki長智慧.. 下次注意注意..
文章標籤
全站熱搜
創作者介紹
創作者 changeway 的頭像
changeway

居家。敗家。資訊阿宅

changeway 發表在 痞客邦 留言(4) 人氣(11,400)