C C 中結構體占用記憶體大小的計算方法

2021-07-23 09:45:47 字數 1821 閱讀 6132

引言

結構體在c語言中雖然經常使用,但是怎麼計算乙個結構體占用多大的記憶體,很多c語言的新手都沒注意過,其實c語言的語法簡單,難就難在它更偏向於與底層,與記憶體打交道。對於嵌入式方面來說,對c語言的要求更高,因為有些硬體的記憶體並不像我們使用的電腦的記憶體那麼充裕,所以需要節約記憶體。

結構體中同樣的變數個數,卻可能導致占用記憶體的大小不同。

例子1:

#include int main()

test;

test e;

printf("%d", sizeof(test));

return 0;

}

輸出的結果為:32

例子2:

#include int main()

test;

test e;

printf("%d", sizeof(test));

return 0;

}

輸出的結果為:24 

只是調換了一下int c和double d的位置,就導致了前者比後者多占用了8個位元組的記憶體。這只是乙個小例子。那麼,結構體中到底怎麼計算記憶體的呢。

計算規則

首先需要介紹有效對齊值:每個平台上的編譯器都有預設對齊係數n,可以通過#pragma pack(n)來指定。有效對齊值就等與該對齊係數和結構體中最長的資料型別的長度兩者最小的那乙個值,比如對齊係數是8,而結構體中最長的是int,4個位元組,那麼有效對齊值為4。

結構體的記憶體計算方式遵循以下規則:

1.資料成員對齊規則:第乙個資料成員放在offset為0的地方,以後的每乙個成員的offset都必須是該成員的大小與有效對齊值相比較小的數值的整數倍,例子1中第乙個資料成員是int 型,第二個是double,有效對齊值為8,所以double的起始位址應該為8,所以第乙個int加上記憶體補齊用了8個位元組

2.結構體作為成員:如果乙個結構裡有某些結構體成員,則結構體成員要從其內部有效對齊值的整數倍位址開始儲存。(比如struct a中存有struct b,b裡有char, int, double,那b應該從8的整數倍開始儲存)

3.收尾工作:結構體的總大小,必須是其有效對齊值的整數倍,不足的要補齊。

有了這些規則,再來看上面的兩個例子。

例子1中,int為第乙個資料成員,所以下乙個儲存的起始位置是4,但是double佔8個位元組,按規則一,不滿足8的倍數,填充到16,char一共有10個位元組(陣列在記憶體中的表示會分解成單個的),即總共26,進行收尾工作,有效對齊值為8,26不滿足8的倍數,填充到32。

例子2中,double為第乙個資料成員,所以下乙個儲存的起始位置是8,按規則一,占用了12個位元組,char有10個位元組,一共用了22個位元組,進行收尾工作,該結構體中有效對齊值為8,22不滿足8的倍數,填充到24。例子

下面給你乙個question,考察你是否懂了上面的規則

#include #pragma pack(8)

int main()

; printf("%d", sizeof(test));

return 0;

}

#include #pragma pack(16)

int main()

printf("%d", sizeof(test));

return 0;

}

如果你計算得出的答案分別為40和48,那我相信你就懂了記憶體對齊的奧秘了。

C語言中結構體占用記憶體大小

這個問題很經典,很容易出現,也叫記憶體的4k對齊吧 cpu傳輸資料的方式 cpu每次傳輸資料大小由它的總線條數決定,32位傳輸4個位元組,64位傳輸8個位元組。這裡以64位系統舉例,若宣告乙個變數大小為8位元組,起始位址位1,而cpu讀取的位址為0 7,則該變數需要讀取兩次,顯然降低了cpu的效能。...

乙個結構體占用記憶體大小的問題

先來看下面的示例 struct demo int main 毫無疑問,都會說,結果為 8 這時我提出乙個問題?請問在32位和64位pc機上分別是多少,或許有些人就有些迷茫了。實際上都等於 8,這時候可能有些人更加疑惑了 實際上 int 型資料在32位 64位都只占用4位元組 下面我們再看乙個例子 s...

類的占用記憶體大小

1.類的大小為類的非靜態成員資料的型別大小之和,也 就是說靜態成員資料不作考慮。2.普通成員函式與sizeof無關。3.靜態成員並不屬於某個物件,sizeof取的是物件大小。4.虛函式由於要維護在虛函式表,所以要佔據乙個指標大小,也就是4位元組。5.空類的sizeof為1。因為乙個空類也要例項化,所...