簡單理解結構體的記憶體對齊

2021-10-09 06:44:44 字數 2480 閱讀 1422

記憶體對齊三原則:

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

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

結構體的總大小,也就是sizeof的結果,.必須是其內部最大成員的整數倍.不足的要補齊。

首先了解記憶體對齊是什麼?

簡單來講記憶體對齊是一種提高記憶體訪問速度的策略,cpu在訪問未對其的記憶體需要經過倆次記憶體訪問,而經過記憶體對齊一次就可以了。

首先第一點要知道的是,記憶體對齊預設為4位元組對齊,當有比4位元組更大的型別時,按更大的型別的位元組進行對齊。

例如:

#include

/*此時 examples結構體的大小為24位元組

ls.a的起始位址是 00dafd90

ls.b的起始位址是 00dafd92

ls.c的起始位址是 00dafd98

由上可證明 記憶體對齊的預設對齊大小為 4位元組,當有比4位元組更大的型別時,按更大的型別的位元組進行對齊。

但是同樣也要注意一點,記憶體對齊的標準時對於不同型別的資料成員之間的對齊。

然後我們由上例進行進一步的改造來加深一下我們對記憶體對齊的理解

#include

using

namespace std;

struct examples

;int

main()

/*此時 examples結構體的大小為24位元組

ls.a的起始位址是 010ff8b4

ls.b的起始位址是 010ff8b8

ls.c的起始位址是 010ff8bc

ls.d的起始位址是 010ff8c4

ls.f的起始位址是 010ff8c6

首先我們來看一下這個結構體各個成員的記憶體大小

a = 4位元組

b = 4位元組

c = 8位元組

d = 2位元組

f = 6位元組

結構體大小為 4 + 4 + 8 + 2 + 6 =24

然後我們來理解一下為何各個資料成員的記憶體大小為這些呢?

1、a為何為4位元組

a 為 char 型別 1 位元組的資料成員,而 b 為int 型別4 位元組的資料成員。所以 a要對b進行記憶體對齊,所以此時的 a為4個位元組。

2、b為何也為4位元組

c 的型別為 long long ,8位元組的資料成員。b為4位元組,所以按照記憶體對齊規則,此時的 b應該為8位元組才對,為何是4位元組呢?因為 a的記憶體大小此時也為4位元組,4 + 4 = 8位元組 同樣符合記憶體對齊規則,所以此時的b也為4位元組。同理 d 與 f 也可套用此原理。d 的記憶體大小為2位元組,而 f 的記憶體大小為6位元組,2 + 6 = 8,同樣符合記憶體對齊規則。原因就是記憶體位址對齊時,如果資料成員之間的大小相加不超過需要對齊的記憶體大小時,多個資料成員會整合到同乙個記憶體空間中。

我們依舊可以使用乙個例子來證明:

#include

using

namespace std;

struct examples

;int

main()

/*此時 examples結構體的大小依舊為24位元組

ls.a的起始位址是 00d6fec4

ls.g的起始位址是 00d6fec6

ls.b的起始位址是 00d6fec8

ls.c的起始位址是 00d6fecc

ls.d的起始位址是 00d6fed4

ls.f的起始位址是 00d6fed6

結構體對齊(記憶體對齊

有的時候,在腦海中停頓了很久的 顯而易見 的東西,其實根本上就是錯誤的。就拿下面的問題來看 structt 使用sizeof t 將得到什麼樣的答案呢?要是以前,想都不用想,在32位機中,int是4個位元組,char是1個位元組,所以t一共是5個位元組。實踐出真知,在vc6中測試了下,答案確實8個位...

記憶體對齊 結構體對齊

現在已知32位機器上各種資料型別的長度如下 char 1 有符號無符號同 short 2 有符號無符號同 int 4 有符號無符號同 long 4 有符號無符號同 float 4 double 8 重要規則 1,複雜型別中各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個型別的位...

C語言 結構體與記憶體對齊準則簡單理解

平時基本不涉及這個問題,被問起才發現沒那麼簡單。一,結構體 記憶體中所有型別位元組之和 includestruct icd struct cdi struct merge int main void 1.首先要找到結構題中所佔位元組數最大的型別,icd中最大位元組數為8,則int為4,char為1,...