C語言 位元組對齊(記憶體對齊)

2022-03-12 03:09:28 字數 3463 閱讀 3048

1)平台原因(移植原因):不是所有的硬體平台都能訪問任意位址上的任意資料,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常

2)硬體原因:經過記憶體對齊之後,cpu的記憶體訪問速度大大提公升。

1.  對齊原則:

【原則1】資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

【原則2】結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

【原則3】結構體作為成員:如果乙個結構裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存。

備註:陣列成員按長度按陣列型別長度計算,如char t[9],在第1步中資料自身長度按1算,累加結構體時長度為9;第2步中,找最大資料長度時,如果結構體t有複雜型別成員a,該a成員的長度為該複雜型別成員a的最大成員長度。

小結:當#pragma pack的n值等於或超過所有資料成員長度的時候,這個n值的大小將不產生任何效果。

注意】(對齊位數跟處理器位數和編譯器都有關)vs, vc等編譯器預設是#pragma pack(8),所以測試我們的規則會正常;注意gcc預設是#pragma pack(4),並且gcc只支援1,2,4對齊。套用三原則裡計算的對齊值是不能大於#pragma pack指定的n值。

2. 自然對齊存放變數的位址要是該變數資料型別大小的整數倍。如:存放int型資料的位址一定要是4的倍數,存放short型資料的位址一定要是2的倍數。

3. 改變預設的對界條件(指定對界):

例1:

#pragma pack(1)

struct aa

;#pragma pack()

結果:8個位元組

例2:

#pragma pack(2)

struct aa

;#pragma pack()

結果:10個位元組

例3:

#pragma pack(4)

struct aa

;#pragma pack()

結果:12個位元組

例4:

#pragma pack(8)

struct aa

;#pragma pack()

結果:12個位元組  

例5:

struct ee  //8個位元組對齊

; //整體對齊係數 = min((max(int,short,char), 8) = 4,將記憶體大小由17補齊到4的整數倍20

char d; //長度1 < 8 按1對齊;偏移量為21;存放位置區間[21]

//整體對齊係數 = min((max(int,short,char), 8) = 4,將記憶體大小由21補齊到4的整數倍24

; //整體對齊係數 = min((max(int,double,float), 8) = 8,將記憶體大小由28補齊到8的整數倍32

};

**1:

#include typedef struct

testlength1;

int length1 = sizeof(testlength1); //4個位元組對齊,占用位元組1111 1011 1000,length = 12

typedef struct

testlength2;

int length2 = sizeof(testlength2); //4個位元組對齊,占用位元組1011 1111 1000,length = 12

typedef struct

testlength3;

int length3 = sizeof(testlength3); //4個位元組對齊,占用位元組1100 1111 1100,length = 12

typedef struct

testlength4;

int length4 = sizeof(testlength4); //4個位元組對齊,占用位元組1111 1111,length = 8

int main(void)

vs2017輸出結果:

**2:

#include #pragma pack(2)

typedef struct

testlength1;

int length1 = sizeof(testlength1); //2個位元組對齊,占用位元組11 11 10 11 10,length = 10

typedef struct

testlength2;

int length2 = sizeof(testlength2); //2個位元組對齊,占用位元組10 11 11 11 10,length = 10

typedef struct

testlength3;

int length3 = sizeof(testlength3); //2個位元組對齊,占用位元組11 11 11 11,length = 8

typedef struct

testlength4;

int length4 = sizeof(testlength4); //2個位元組對齊,占用位元組11 11 11 11,length = 8

int main(void)

vs2017輸出結果:

vs2017輸出結果: 48 24

**4:

#includeusing namespace std;

#pragma pack(2)

typedef struct bb

bb;typedef struct aa

aa;int main()

vs2017輸出結果:32 16 

1. 5分鐘搞定記憶體位元組對齊

2.  快速理解位元組對齊問題

3.  關於面試題中結構體內存對齊計算總結

C語言記憶體位元組對齊

在c語言面試和考試中經常會遇到記憶體位元組對齊的問題。今天就來對位元組對齊的知識進行小結一下。首先說說為什麼要對齊。為了提高效率,計算機從記憶體中取資料是按照乙個固定長度的。以32位機為例,它每次取32個位,也就是4個位元組 每位元組8個位,計算機基礎知識,別說不知道 位元組對齊有什麼好處?以int...

資料對齊 C語言 記憶體位元組對齊詳解

一 什麼是對齊,以及為什麼要對齊 1.現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。2.對齊的作...

資料對齊 C語言 記憶體位元組對齊詳解

修改部分語言錯誤 一 什麼是對齊,以及為什麼要對齊 1.現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是...