在結構體中記憶體對齊的規則及其重要性

2021-08-28 03:25:42 字數 1778 閱讀 9741

記憶體分配的規則:①第乙個成員在與結構體變數偏移量為0的位址處。

②從第二個成員開始,每個成員都要對齊到它自身對齊數的整數倍的位址處(每個成員的對齊數是自身的大小和預設對齊數的較小值,vs平台下的預設對齊數是8,linux下的是4) 。

③結構體的總大小必須是所有對齊數裡面最大的那個對齊數的整數倍

修改預設對齊數:

#pragram pack(4)//把預設對齊數改為4

#pragram pack()//取消對預設對齊數的修改

windows下vs平台預設對齊數可改為(1,2,4,8)。

linux下預設對齊數可改為(1,2,4)。

下面寫幾個例題加深理解

栗子1

:struct a;

int main()

上面求出來sa的大小是24個位元組,我們來分析一下。

(1) c 這個字元變數從0偏移處開始存,總大小是乙個位元組。

(2)第二個成員是double型的,大小為8個位元組,而預設對齊數是8,所以它 的對齊數是8。

根據規則②它要對齊到它的對齊數的整數倍上,b的儲存位置就是8偏移處—16偏移處。那麼它與第乙個變數c之間就空了7個位元組,這7個位元組就浪費掉了。

(3)第三個成員是int型的,佔4個位元組,預設對齊數是8,取較小值,所以它的對齊數是4,正好從16偏移處開始存,i就存在16偏移處到20偏移處。

最後再看看規則③。我們知道這裡面最大對齊數是8,但20並不是8的倍數,所以後面還要再加四個位元組的空間。所以總大小24就是這麼算出來的。

栗子2

:struct a;

struct b;

int main()

看看這個,可能會迷惑這個結構體b中又有乙個結構體變數sa,那sa的對其規則是啥?這裡的結構體變數sa的對齊數是取struct a中所有對齊數裡面最大的那個對齊數,所以這裡sa的對齊數是8,而sa的大小是24。最後算出來sb的大小是32。

平台原因(移植原因):

不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能

在某些位址處取某些特定型別的資料,否則丟擲硬體異常。

效能原因:

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

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

記憶體訪問僅需要一次訪問。

總結:

結構體的記憶體對齊是拿空間來換取時間的做法

那在設計結構體的時候,我們既要滿足對齊,又要節省空間:

讓占用空間小的成員盡量集中在一起。

struct a;

struct

b;

像這兩個結構體占的記憶體大小是不同的,第乙個結構體占記憶體是40位元組,第二個佔的記憶體是24位元組。但是這兩個結構體裡面元素是一樣的,但耗費的空間資源不同。

結構體的記憶體對齊規則

前言 結構體是一種自定義型別,其中包含了許多不同型別的變數,我們稱這些值為成員變數,那麼這種自定義型別的大小該怎麼計算呢?這才是我們今天討論的重點問題。要想計算結構體的大小,首先得了解結構體的記憶體對齊規則。對齊數 編譯器預設的對齊數 vs為8 linux為4 與 該成員大小的較小值 下面我們看兩個...

結構體在記憶體中的對齊規則

結構體在記憶體中的對齊規則 標籤 儲存 struct 測試iostream c2011 11 15 19 32 4717人閱讀 9 收藏 舉報乙個結構體變數定義完之後,其在記憶體中的儲存並不等於其所包含元素的寬度之和。例一 include using namespace std struct x c...

記憶體對齊的規則及其作用

首先由乙個程式引入話題 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 程式的輸出結果為 sizeo...