這酷兄逛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長智慧..
下次注意注意..
- Aug 18 Sat 2007 23:55
Data structure alignment
close
全站熱搜
留言列表
發表留言