2010年6月21日 星期一

C語言中資料結構(struct)的大小 - __attribute__((packed))

通常在PC上寫程式時,很少會去管struct會佔掉多少記憶體。

當要使用到時,也不會想去用手算到底佔掉多少,大多是直接使用sizeof來做計算。

然而sizeof計算出來的值往往不會如我們想的一樣。因為compiler為了效能考量,會自動地為我們

做最佳化,也就是資料對齊。為了這個目的,compiler會為struct多準備一些記憶體。

我們可以看以下的code:

struct ABC {

int index;

char name[6];

int score;

};



struct DEF{

int att;

char name[3];

};



int main(void)

{

printf("sizeof(ABC) = %d\n", sizeof(struct ABC));

printf("sizeof(DEF) = %d\n", sizeof(struct DEF));

return 0;



}

說明:

1. 若我們直接去計算struct ABC和strcut DEF時,

struct ABC = 4 + 6 + 4 = 14 (struct ABC用掉14個byte)

strcut DEF = 4 + 3 = 7 (struct DEF用掉7個byte)

2. 但真的是這樣嗎?程式執行出來的結果卻是,

sizeof(ABC) = 16

sizeof(DEF) = 8

3. 這就是compiler為我們做了對齊的最佳化,將這二個的struct都調整成2的次方。

這樣有利於運算。



這樣的做法在PC上通常沒有問題,但若是在嵌入式系統上,記憶體必需要錙珠必較時

,我們就必須要考量到使用struct所佔掉的記憶體空間,可以使用__attribute__((packed));這個關鍵字,

它的作用在於叫compiler不要為我們做對齊的最佳化,因此,計算的結果就會如同我們所想的一樣了。

struct ABC {

int index;

char name[6];

int score;

} __attribute__((packed));;



struct DEF{

int att;

char name[3];

} __attribute__((packed));;



int main(void)

{

printf("sizeof(ABC) = %d\n", sizeof(struct ABC));

printf("sizeof(DEF) = %d\n", sizeof(struct DEF));

return 0;



}

這樣就會得到以下的結果了。

sizeof(ABC) = 14

sizeof(DEF) = 7



這裡沒有哪一種用法比較好的問題,端看在使用上的需求,

要運算速度快,就需要資料對齊。要節省記憶體的使用,就取消對齊。
 
 
ref:http://zylix666.blogspot.com/2007/10/cstruct.html

8 則留言:

  1. 你好, 我剛好逛到你的部落格. 你的這篇寫的相當精闢, 可否借我轉貼到我的部落格嗎? 我會標明出處的.. 謝謝!!

    回覆刪除
  2. 突然搜到這篇文章~!解了我個人的迷惑!謝謝~

    回覆刪除
  3. 很清楚的解說 感謝

    回覆刪除
  4. simple and good,
    thanks.

    回覆刪除

DNSSEC安全技術簡介 作者:游子興 / 臺灣大學計算機及資訊網路中心網路組約聘幹事 DNS 是一套已經廣泛使用的Internet 服務,但因先天的技術限制導致容易成為駭客攻擊的目標。本文主要在介紹DNSSEC 之緣起與技術背景,及其使用的加解密技術如何確保資料的完整...