1. 程式人生 > >【易錯】C語言結構體記憶體對齊問題

【易錯】C語言結構體記憶體對齊問題

對於一個結構體的位元組數大家有沒有遇到什麼疑問呢?

先看一個結構體:
typedef struct Test
{
char a1;
int a2;
char a3;
short a4;
}Test_T;

在32位編譯系統下這一個結構體的位元組數是多少呢?是1+4+1+2=8位元組嗎?不是的,實際結果為12位元組。為什麼呢?因為編譯器會對不足4位元組的變數空間自動補齊為4個位元組(這就是記憶體對齊),以提高CPU的定址效率(32位CPU以4個位元組步長定址的)。

記憶體對齊是編譯器的“管轄範圍”。編譯器為程式中的每個”資料單元“安排在適當的位置上,以便於能快速的找到每個“資料單元”。對於32bit的CPU,其定址的步長為4個位元組(即unsigned int 位元組長度),這就是常說的“4位元組對齊”。同理,對於64bit的CPU,就有“8位元組對齊”。本文以32位的CPU為例。

請看下面程式碼:
#include <stdio.h>

typedef struct Test
{
char a1;
int a2;
char a3;
short a4;
}Test_T;

int main(void)
{
Test_T T;

printf("\nsizeof(T) = %d\n", sizeof(T));
printf(“a1地址:%d\n”, (unsigned int)&T.a1);
printf(“a2地址:%d\n”, (unsigned int)&T.a2);
printf(“a3地址:%d\n”, (unsigned int)&T.a3);
printf(“a4地址:%d\n”, (unsigned int)&T.a4);

return 0;
}

執行結果為:

可見,正好印證了上述的說法,補齊之後結構體成員a1,a2,a3的地址之間正好相差4個位元組,a3與a4之間相差兩個位元組也是因為在其中多留出了1個空白位元組。該程式的執行結果可形象地描述為下圖:

a1只佔用一個位元組,為了記憶體對齊保留了三個空白位元組;a3和a4加起來共3位元組,為了記憶體對齊保留了1個空白位元組。這就是編譯器儲存變數時做的見不得人的”手腳“,以方便其僱主——CPU能更快地找到這些變數。

PS:上圖中使用的開發環境為MinGW+Notepad++,可移步至下載安裝包,很酷的開發環境哦,可以讓你找到程式設計的感覺。如果閒MinGW配置麻煩,也可移步至下載一款精悍的編譯器。

【每日一句】
考慮一千次,不如去做一次;猶豫一萬次,不如實踐一次。華麗的跌倒,勝過無謂的徘徊,邁出第一步,你就成功了一半。

想學習c語言的同學可以加主頁的程式語言學習群:859093189 呦~每天晚上8點會有免費的c語言0基礎公開課教學,有時間的時候也是可以幫助大家解答一些問題的!