1. 程式人生 > >C語言中結構體佔用記憶體問題

C語言中結構體佔用記憶體問題

之前對結構體佔用記憶體一直很混亂,到底是按照哪個變數型別計算記憶體?還是怎麼計算?下面先看一個例子:

1

2

3

4

5

6

7

struct str1

{

char a;

int b;

float c;

double d;

};

str1這個結構體佔用的記憶體是多少呢?如果用變數型別直接想加,得到的結果是17,但顯然不是這樣的。這個程式執行的正確結果是24.為什麼呢?

  因為為了CPU能夠快速訪問,提高訪問效率,變數的起始地址應該具有某些特性,這就是所謂的“對齊”。比如4位元組的int型變數,那它的起始地址就應該在4位元組的邊界上,即起始地址可以被4整除。

  記憶體對齊的規則很簡單:

  1.起始地址為該變數型別所佔記憶體的整數倍,若不足則不足部分用資料填充至所佔記憶體的整數倍。

  2.該結構體所佔總記憶體為結構體成員變數中最大資料型別的整數倍。

  接下來我們分析上面的例子:

  char型變數佔一個位元組,所以它的起始地址為0,而int型別佔4個位元組,它的起始地址應該是4(的整數倍),那麼記憶體地址1、2、3就需要被填充。同樣,float佔用4個位元組,而結構體中a,b兩個成員變數佔了0~7記憶體地址,c的地址從8開始,符合規則一,佔用記憶體地址為8~11。double型別佔8個位元組,所以d的起始地址就應該從16開始,那麼12、13、14、15記憶體地址就需要被填充。d從16地址開始,佔用8個位元組。整個結構體佔用位元組數為24,符合規則二。記憶體分配如圖:紅色區域為填充部分

下面再舉一個例子,進一步說明:

1

2

3

4

5

6

7

struct str2

{

double a;

int b;

char c;

double d;

};

str2這個結構體佔用的記憶體空間是多少呢?是24!怎麼分析呢?

首先double型別的a佔用記憶體地址為0~7,int型別的b起始地址為8,符合規則一,佔用地址為8~11,char型別的c佔一個位元組,地址為12.那麼double型別的d,起始地址為13嗎?顯然不是,滿足規則一的地址是16,所以d起始地址為16,佔用16~23。結構體總共24個位元組,滿足規則二。如果這個結構體最後再加一個成員變數 char e,那這個結構體佔用的記憶體是多少?char型別的e起始地址為24,佔用地址為24,但是結構體一種有25個位元組,就不滿足規則二了,怎麼辦呢?為了滿足規則二,我們將25~31進行填充,因此整個結構體佔用32個位元組。

這就是結構體記憶體佔用問題的分析方法。由於水平有限,有什麼問題希望讀者不吝賜教!