結構體記憶體對齊模式
阿新 • • 發佈:2018-11-02
結構體的位元組大小,一個簡單的結構體定義如下,這個結構的大小應是8位元組(32位下)
typedef struct MODEL4 {
char c;
int x;
}MODEL4;
char的大小是1,而int是4,但總的大小是8,這就是結構體記憶體對齊的原因。在32位的機器上,資料是以4位元組對齊的,因為這樣子,cpu訪問起來會很方便。
這個結構體的記憶體裡面的影象大概是這樣的:
圖中紫色部分的記憶體確實沒有用,就是為了對齊而多申請的。
關於結構體記憶體對齊,下面的例子更經典 在我資料結構課的時候當時沒有很好的理,要很好的理解作業系統這樣的做法,一定要從記憶體的角度去理解。
typedef struct MODEL{
int x;
char y;
double z;
}MODEL;
// 4 + 4 + 8
typedef struct MODEL2{
char x;
double y;
int z;
}MODEL2;
// 4 + 4 + 8 + (4 + 4)
還是畫成圖更形象一些。
不過關於結構體的記憶體對齊。就是這些幾點規則
1:每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是陣列,結構體等)的整數倍開始(比如int在32位機為4位元組,則要從4的整數倍地址開始儲存。
2:結構體作為成員:如果一個結構裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始存 儲.(struct a裡存有struct b,b裡有char,int ,double等元素,那b應該從8的整數倍開始儲存.)
3:結構體的總大小,也就是sizeof的結果,.必須是其內部最大成員的整數倍.不足的要補齊.
這個結構體就是結構體裡面有一個結構體作為成員出現
typedef struct MODEL3 {
int x;
MODEL2 y;
char z;
}MODEL3;
// (4+4) + 24 + (1+7) = 40
關於記憶體對齊模式,計算機預設的32位是4位元組對齊,c語言可以通過#pragma pack(n)對齊
#pragma pack(n)
比如#pragma pack(1) 結構體的大小就不一樣了
#pragma pack(1)
#include<stdio.h>
typedef struct MODEL{
int x;
char y;
double z;
}MODEL;
// 4 + 4 + 8
typedef struct MODEL2{
char x;
double y;
int z;
}MODEL2;
// 4 + 4 + 8 + (4 + 4)
typedef struct MODEL3 {
int x;
MODEL2 y;
char z;
}MODEL3;
// (4+4) + 24 + (1+7) = 40
typedef struct MODEL4 {
char c;
int x;
}MODEL4;
int main(void) {
MODEL model1 = {0};
MODEL2 model2 = {0};
MODEL3 model3 = {0};
printf("MODEL = %d\n", sizeof(MODEL));
printf("MODEL2 = %d\n", sizeof(MODEL2));
printf("MODEL3 = %d\n", sizeof(MODEL3));
printf("MODEL4 = %d\n", sizeof(MODEL4));
printf("model1.x = %p, model1.y = %p, model1.z = %p\n", &model1.x, &model1.y, &model1.z);
printf("model2.x = %p, model2.y = %p, model2.z = %p\n", &model2.x, &model2.y, &model2.z);
printf("model3.x = %p, model3.y = %p, model3.z = %p\n", &model3.x, &model3.y, &model3.z);
return 0;
}
輸出: