記憶體對齊計算可謂是筆試題的必考題,但是如何按照計算原則算出正確答案一開始也不是很容易的事,所以專門通過例子來複習下關於結構體內存對齊的計算問題。(編譯環境為vs2015)
對齊原則:原則1:資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。原則2:結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。
原則3:結構體作為成員:如果乙個結構裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存。
預設對齊值:linux 預設#pragma pack(4)例一:一位元組對齊第一步: 成員資料對齊window 預設#pragma pack(8)
注:可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一係數,其中的n就是指定的「對齊係數」。
#pragma pack(1)
struct aa ;
#pragma pack()
第二步: 整體對齊整體對齊係數 = min((max(int,short,char), 1) = 1,所以不需要再進行整體對齊。整體大小就為8。
圖示如下:
例二:二位元組對齊
第一步: 成員資料對齊
#pragma pack(2)
struct aa ;
#pragma pack()
第二步: 整體對齊整體對齊係數 = min((max(int,short,char), 2) = 2,將9提公升到2的倍數,則為10.所以最終結果為10個位元組。
圖示如下:(x為補齊部分)
例三:四位元組對齊
第一步: 成員資料對齊
#pragma pack(4)
struct aa ;
#pragma pack()
第二步: 整體對齊整體對齊係數 = min((max(int,short,char), 4) = 4,將9提公升到4的倍數,則為12.所以最終結果為12個位元組。
圖示如下:(x為補齊部分)
例三:八字節對齊
第一步: 成員資料對齊
#pragma pack(8)
struct aa ;
#pragma pack()
第二步: 整體對齊整體對齊係數 = min((max(int,short,char), 8) = 4,將9提公升到4的倍數,則為12.所以最終結果為12個位元組。圖示如上。
注:可以通過stddef.h庫中的offsetof巨集來檢視對應結構體元素的偏移量。
例四:結構體中包含結構體的運算
整體計算過程如下
struct ee
; //整體對齊係數 = 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
整體計算過程如下
struct b ;
//整體對齊係數 = min((max(int,double,float), 8) = 8,將記憶體大小由28補齊到8的整數倍32
會了關於結構體記憶體大小的計算,可是為什麼系統要對於結構體資料進行記憶體對齊呢,很明顯所占用的空間大小要更多。原因可歸納如下:1、平台原因(移植原因):不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。
2、效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。
更簡單的說明下:如圖
首先,cpu的訪問粒度為4,也就是一次性可以讀取記憶體中的四個位元組內容;當我們不採用記憶體對齊策略,如果需要訪問a中的b元素,cpu需要先取出0~3四個位元組的內容,發現沒有讀取完,還需要再次讀取,一共需要進行兩次訪問記憶體的操作;而有了記憶體對齊,參考左圖,可一次性取出4~7四個位元組的元素也即是b,這樣就只需要進行一次訪問記憶體的操作。所以作業系統這樣做的原因也就是所謂的拿空間換時間,提高效率。
建議:雖然作業系統會浪費空間來完成記憶體對齊,但是我們有了上面的知識可以通過按照資料型別來調整結構體內部的資料的先後順序來儘量減少記憶體的消耗;例如我們將下面結構體a中的順序調整為b,sizeof(a)的結果為12,而sizeof(b)的結果就是8:
struct a
;struct b
;
關於結構體,記憶體對齊,sizeof
程式設計師寶典中,關於結構體對齊問題,看了一晚上帖子,包括記憶體,cpu等等的,現在總算有些理解 要弄清結構體對齊,首先要明白為什麼要對齊?1.先想想簡單的hello.c整個執行過程中外設,記憶體,cpu的工作過程 計算機的所有工作都是要經過記憶體的,包括網頁得讀取等等 我們平時說的32位機器是指指...
關於結構體內存對齊方式
結構體的對齊方式必須是程式設計師所了解的,關於記憶體對齊方式的優點和部分知識可以參閱http www.ibm.com developerworks library pa dalign 結構體占用的儲存空間 struct sizeof 概要 結構體所占用的空間只可能是 1,2,4,6,8.結構體的記憶...
結構體內存對齊
結構體內存對齊 一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這...