記憶體對齊相關問題詳解

2021-08-19 22:43:18 字數 2142 閱讀 6596

目錄:

記憶體對齊問題是筆試、面試中乙個非常重要的問題,不僅在筆試、面試中很重要,它對於我們理解資料在記憶體中的儲存也有很深刻的意義,所以在這裡進行一次總結。

我們現在使用的算機中記憶體空間都是按照位元組(byte)劃分的,理論上說,似乎對任何型別的變數的訪問可以從任意位址開始,但實際情況則是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別的資料按照一定的規則在記憶體空間上排列,而不是順序的乙個接乙個地排放,這就是對齊。

linux 預設#pragma pack(4)

window 預設#pragma pack(8)

注:可以通過預編譯命令#pragma pack(n) ,n=1,2,4,8,16來改變這一係數,其中的n就是指定的「對齊係數」。

1.第乙個成員在與結構體變數位址偏移量為0的位址處(即第乙個成員存放在結構體的首位址處);

2.其它成員變數要對齊到某個數字(對齊數)的整數倍位址處。對齊數=編譯器預設的對齊數與該成員大小的較小值(我們會在後面詳細講解);

3.結構體總大小為最大對齊數的整數倍(通過第二條我們知道,結構體中每乙個成員都有乙個自己對應的對齊數);

4.如果有巢狀結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(包含巢狀結構體)的整數倍。

1.平台原因

不是所有的硬體平台都能訪問任意位址上的任意資料;某些硬體平台只能在某些位址處取某些特定型別的資料,否則會丟擲硬體異常。

2.效能原因

資料結構(尤其是棧)應該盡可能在自然邊界上對齊。

原因在於,為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問;而對其的記憶體訪問僅需要一次訪問。

總的來說,結構體內存對齊就是拿空間換取時間的做法。

第一步: 成員資料對齊

#pragma pack(1)//指定編譯器對齊數為1

struct aa ;

第二步: 整體對齊

整體對齊係數 = 1(每個資料成員對齊數分別為1 1 1 1),所以不需要再進行整體對齊。整體大小就為8。

圖示如下:

第一步: 成員資料對齊

#pragma pack(2)

struct aa ;

第二步: 整體對齊

整體對齊係數 = 2(每個資料成員的對齊數分別為2 1 2 1,最大對齊數為2),將9提公升到2的倍數,則為10.所以最終結果為10個位元組。

第一步: 成員資料對齊

#pragma pack(4)//指定編譯器4位元組對齊

struct aa ;

第二步: 整體對齊

整體對齊係數 = 4(每個成員對應的對齊數分別為:4 1 2 1,最大對齊數為4),將9提公升到4的倍數,則為12.所以最終結果為12個位元組。

第一步: 成員資料對齊

#pragma pack(8)//指定編譯器8位元組對齊

struct aa ;

第二步: 整體對齊

整體對齊係數 = 4(每個成員的對齊數分別為:4 1 2 1,最大對齊數為4),將9提公升到4的倍數,則為12.所以最終結果為12個位元組。

第一步:資料成員對齊

#pragma pack(8)//指定編譯器8位元組對齊

struct ee

; //struct ff整體對齊係數 = 4(struct ff中成員的對齊數分別為:4 1 2 1,最大對齊數為4)

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

};

第二步:整體對齊

整體對齊係數 = 4(資料成員對齊數分別為 4 1 2 4(結構體中巢狀結構體的最大對齊數) 1,最大對齊數為4),將記憶體大小由21補齊到4的整數倍24

第一步:成員對其

#pragma pack(8)//指定編譯器8位元組對齊

struct b ;

};

第二步:整體對齊

整體對齊係數 = 8(結構體成員對齊數分別為:2 2 8(struct a的最大對齊數),最大對齊數為8),將記憶體大小由28補齊到8的整數倍32。

記憶體對齊詳解

首先由乙個程式引入話題 程式的輸出結果為 sizeof st1 is 12 sizeof st2 is 8 問題出來了,這兩個一樣的結構體,為什麼sizeof的時候大小不一樣呢?對於大多數的程式設計師來說,記憶體對齊基本上是透明的,這是編譯器該幹的活,編譯器為程式中的每個資料單元安排在合適的位置上,...

記憶體對齊詳解

首先由乙個程式引入話題 1 環境 vc6 windows sp2 2 程式1 3 include 4 5 using namespace std 6 7 struct st1 8 13 14 struct st2 15 20 21 int main 22 23 cout sizeof st1 is ...

記憶體對齊詳解

一 為什麼會有c 記憶體對齊 以下內容節選自 intel architecture 32 manual 為了提高程式的效能,資料結構 尤其是棧 應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問 然而,對齊的記憶體訪問僅需要一次訪問。乙個字或雙字運算元跨越了4...