看如下結構體:
#include <stdio.h>
typedef struct _STU
{
int id;
char name[20];
char sex;
int age;
float score;
char addr[30];
}STU;
int main()
{
STU s;
printf("%d\n", sizeof(s));
return 0;
}
#include <stdio.h>
typedef struct _STU
{
int id;
char name[20];
char sex;
char addr[30];
int age;
float score;
}STU;
int main()
{
STU s;
printf("%d\n", sizeof(s));
return 0;
}
這兩個結構體的成員是一摸一樣的,只是位置發生了變化,爲什麼他們倆所佔的內存空間就不一樣呢,而且按平常算結構體變量空間的方法來算,這個結構體應該是(4+20+1+4+4+30)=63個字節,但是並沒有一個答案是63.
這就是因爲內存對齊:
如圖所示:
(1)這是一個結構體變量在開闢存儲空間,結構體變量的第一個成員變量是int型,他的偏移量爲min(8,int)=4;而存儲起始位置爲0,可以整除4,所以int從0-4佔了四個字節;
(2)到了第二個成員變量,他的類型是char,而min(8,1)=1;他從4開始,而4可以整除1,所以也不用對齊,而他是一個有20個字節長度的數組;
(3)所以第三個成員變量從24開始,而他也是char型min(8,1)=1,24可以整除1;所以不用對齊,到了25;
(4)下一個成員是int型的,而min(8,int)=4,25不能整除4,所以現在就需要內存對齊,開始補到28,28可以整除4,所以從25–28的內存是空的,這個數據存儲位置從28開始;
(5)下一個成員是int,min(8,int)=4,28可以整除4,不用對齊;
(6)下一個成員是float,min(8,int)=4,32可以整除4,也不用對齊;
現在到了36,下一個成員類型爲charmin(8,1)=1,36可以整除1,不用對齊,最終使用了66個字節的存儲空間,
(7)但是最終整個結構體還要進行一次內存對齊,結構體對齊是系統默認字節數與自己成員中佔最大字節的數進行比較,min(8,4)=4;所以總體應該是4的倍數,所以還需要添加兩個字節在最後面,最終佔了68個字節!
內存對齊的規則:
1.對於結構的各個成員,第一個成員位於偏移爲0的位置,以後的每個數據成員的偏移量必須是 min(系統默認設置的對齊數值,這個數據成員的自身長度)的倍數
2.在所有的數據成員完成各自對齊之後,結構體或聯合體本身也要進行對齊,對齊將按照 系統默認指定的數值和結構或者聯合體最大數據成員長度中比較小的那個 也就是 min(系統默認對齊數值, 長度最長的數據成員);
內存對齊是操作系統爲了快速訪問內存而制定的一種規則,有了內存對齊,操作系統進行查找將會快速的多的多!