C語言查缺補漏 七 結構體內存對齊原則

2021-08-28 16:26:43 字數 1580 閱讀 7015

​ 直到前幾個星期做了一道選擇題才知道,結構體元素的宣告順序可能影響結構體使用時所需的記憶體大小!!!

​ 一查才知道,在c語言中結構體有記憶體對齊原則,這個原則可以總結為兩點:

——資料成員對齊規則:

​ 結構體或聯合體的資料成員,第乙個資料成員放在offset為0的地方,以後每個成員儲存的起始位置為該成員大小(當該成員為基本型別時)或者該成員的最大子成員大小(當該成員為陣列,結構體等時)的整數倍位置

——收尾:

​ 結構體所佔記憶體的總大小,必須是它內部最大成員所佔記憶體大小的整數倍(像陣列,結構體等成員在計算時按其成員的最大成員所佔記憶體算),不是要補齊

struct bb ;					//整個結構體bb所佔記憶體位置為 0~31	

struct aa ; //整個結構體aa所佔記憶體位置0~47

在結構體bb中:

​ int型別id為4位元組,所以占用0~3位置

​ double型別weight為8位元組,它的起始位置必須是8的整數倍,所以它的起始位置為8,占用位置為8~15

​ char型陣列s中最大成員單個char是1位元組,所以char陣列的起始位置必須是1的整數倍,所以它的起始位置為16,而陣列長度為10,總占用位元組為10,所以占用位置為16~25

​ 在結構體bb中,最大成員為double型的weight(有同學會說char s[10]最大,為什麼不是char s[10]?因為char s的最大成員所佔記憶體為1,s按照1進行比較),所以結構體bb總占用記憶體必須為8的整數倍,所以結構體bb的總記憶體位址為0~31

在結構體aa中:

​ char型陣列name陣列長度為2,單個char佔1位元組,陣列總共佔兩位元組,所以占用位置為0~1

​ bb型結構體b中最大成員為double型的weight,所以bb型別的起始位置必須是8的整數倍,也就是8,而結構體bb總占用記憶體是32,所以占用b位置為8~39

​ int型age為4位元組,所以起始位置必須是4的整數倍,也就是40,所以它占用的位置是40~43

​ 在結構體aa中,最大成員是結構體b(它的最大成員weight占用記憶體為8),所以結構體aa總占用記憶體必須是8的整數倍,所以結構體aa的總記憶體位址為0~47

​ 講到這兒,我們會有乙個疑問,c語言為什麼要有對齊原則呢?多浪費空間呀!大家可能知道桶排這種演算法,以空間換時間。對齊原則也不例外,以耗費空間為代價,來加快定址速度。

​ 至於原理:如果乙個結構的最大成員字長為w,那麼系統會假設在這種體系結構上字長為w的資料使用最頻繁,優先提高對w位資料操作。所有的資料訪問都以w位對齊,這樣需要傳輸的位址位減少,定址自然就可以加快。

​ 那麼我們可以自己設定對齊規則嗎?在規定的範圍內是可以的,例如:

​ 在檔案開頭加 #pragma pack(1) //不對齊

​ #pragma pack(2) //支援1,2對齊

​ #pragma pack(4) //支援1,2,4對齊

​ #pragma pack(8) //支援1,2,4,8對齊(預設)

​ 也就是說pack是多少,結構體中的成員它的初始位置最多是多少的倍數

​ 嗯嗯,就醬紫~

​ 如果有寫的不對或者不全面的地方 可通過主頁的****進行指正,謝謝!

C語言結構體內存對齊

1.效能原因 為了提高cup的效率訪問記憶體的速度,若是訪問未對齊的記憶體,處理器需要作兩次訪問 而訪問對齊的記憶體,則只需要一次訪問。2.編譯器相關 有的編譯器已經優化了記憶體對齊,所以記憶體對齊依賴於編譯器。參考 結構體對齊問題 說實話,規則看起來不太好理解,直接模仿下面步驟即可 以32位機器為...

C語言結構體內存對齊

記憶體中存放資料的時候要有一定的規則,這麼做得根本原因是要減少cpu訪問記憶體的次數。舉個例子,int型別為4個位元組,存放int型別的記憶體的起始位址就是4的倍數,這樣cpu訪問一次記憶體就能夠取到資料 跟cpu訪問記憶體的機制有關,加上cache的對映,一般cpu一次訪問64位元組的資料,也有1...

C語言 結構體內存對齊

1 平台原因 不是所有硬體平台都能夠訪問任意位址上的任意資料的,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。2 效能原因 主要原因 資料結構 尤其是棧 應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問 而對齊的記憶體訪問僅需要一次訪問...