C 記憶體對齊原則及作用

2021-10-01 11:34:48 字數 2707 閱讀 2923

內建型別資料成員:結構(struct/class)的內建型別資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員的起始位置要從自身大小的整數倍開始儲存

結構體作為成員: 如果乙個結構裡有某些結構體成員,則結構體成員要從其內部「最寬基本型別成員」的整數倍位址開始儲存(如struct a裡存有struct b,b裡有char, int, double等元素,那b應該從8的整數倍位置開始儲存)。

收尾工作: 結構體的總大小,也就是sizeof的結果必須要對齊到內部"最寬基本型別成員"的整數倍,不足的要補齊。(基本型別不包括struct/class/union)。

sizeof(union)以結構裡面size最大的元素為union的大小,因為在某一時刻,union只有乙個成員真正儲存於該位址。

no.1

class

data;

cout <<

sizeof

(data)

<< endl;

no.2

class

data;

cout <<

sizeof

(data)

<< endl;

顯然程式no.1 輸出的結果為 8,no.2 輸出的結果為 16 .

no.1最大的資料成員是4bytes,1+4=5,補齊為4的倍數,也就是8。而no.2為8bytes,1+8=9,補齊為8的倍數,也就是16。

no.3

class

data;

cout <<

sizeof

(data)

<< endl;

no.4

class

data;

cout <<

sizeof

(data)

<< endl;

no.3執行結果為 12,no.4執行結果為 8

class中的資料成員放入記憶體的時候,記憶體拿出乙個記憶體塊來,資料成員們排隊乙個乙個往裡放,遇到太大的成員時,不是將其劈成兩半能放多少就放多少,而是等下乙個記憶體塊過來。這樣的話,就可以理解為什麼no.3 no.4兩段**輸出結果不一樣了,因為no.3是

1 + (3) + 4 + 1 + (3) = 12,而no.4是1 + 1 + (2) + 4 = 8。括號中為補齊的bytes。

no.5

class

bigdata

;class

data;

cout <<

sizeof

(bigdata)

<<

" "

<<

sizeof

(data)

<< endl;

no.6

class

bigdata

;class

data;

cout <<

sizeof

(bigdata)

<<

" "

<<

sizeof

(data)

<< endl;

no.5和no.6執行結果均為: 33 48

在預設條件下,記憶體對齊是以class中最大的那個基本型別為基準的,如果class中有自定義型別,則遞迴的取其中最大的基本型別來參與比較。在no.5和no.6中記憶體塊乙個接乙個的過來接走資料成員,一直到第5塊的時候,bigdata裡只剩1個char了,將它放入記憶體塊中,記憶體塊還剩7個bytes,接下來是個int(4bytes),能夠放下,所以也進入第5個記憶體塊,這時候記憶體塊還剩3bytes,而接下來是個double(8bytes),放不下,所以要等下乙個記憶體快到來。因此,no.5的data的size = 33 + 4 + (3) + 8 = 48,同理no.6應該是

33 + (7) + 8 = 48。

順便提一下union: 共用體表示幾個變數共用乙個記憶體位置,在不同的時間儲存不同的資料型別和不同長度的變數。在union中,所有的共用體成員共用乙個空間,並且同一時間只能儲存其中乙個成員變數的值。

no.7

classa;

classb;

cout <<

sizeof

(a)<<

" "

<<

sizeof

(b)<< endl;

以上**輸出的結果為: 48 56

對於class a,實際占用41位元組,但會發生8位元組對齊,所以大小為48位元組。對於class b,成員b的起始位置已發生8位元組對齊,而class b整體還會發生8位元組對齊,所以最終大小為56。

效能原因:經過記憶體對齊後,cpu的記憶體訪問速度大大提公升。

在程式設計師看來,記憶體是由乙個個的位元組組成。而cpu並不是這麼看待的,cpu把記憶體當成是一塊一塊的,塊的大小可以是2,4,8,16位元組大小,因此cpu在讀取記憶體時是一塊一塊進行讀取的。塊大小成為memory access granularity(粒度) 本人把它翻譯為「記憶體讀取粒度」 。

假設cpu要讀取乙個int型4位元組大小的資料到暫存器中,分兩種情況討論:

1、資料從0位元組開始

2、資料從1位元組開始

再次假設記憶體讀取粒度為4。

C C 記憶體對齊原則及作用

1 資料成員對齊規則 結構 struct 或聯合 union 的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小 只要該成員有子成員,比如說是陣列,結構體等 的整數倍開始 比如int在 位機為 位元組,則要從 的整數倍位址開始儲存 ...

C 記憶體對齊原則

c 記憶體對齊原則 1 在沒有 pragam pack巨集的情況下,struct class union記憶體對齊原則有四個 資料成員對齊規則 結構 struct 或聯合 union 的資料成員,第乙個資料成員放在offset為0的位置,以後每個資料成員儲存的起始位置都是放在該資料成員大小的整數倍位...

c 記憶體對齊原則

struct class union記憶體對齊原則有四個 1 資料成員對齊規則 結構 struct 或聯合 union 的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小 只要該成員有子成員,比如說是陣列,結構體等 的整數倍開始 比...