結構體在創建的時候,為了能夠滿足平臺和性能原因,需要進行記憶體對齊,結構體的大小是由記憶體對齊的結果而決定的, ——前言
1.結構體記憶體對齊原則:
1. 第一個成員在與結構體變數偏移量為0的地址處,
2. 其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處,
對齊數 = 編譯器默認的一個對齊數 與 該成員大小的較小值,
VS中默認的值為8
3. 結構體總大小為最大對齊數(每個成員變數都有一個對齊數)的整數倍,
4. 如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整
體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍,
1.1
第一個成員在與結構體變數偏移量為0的地址處,
翻譯:
struct c { char a; int b; char c; };當創建結構體開辟空間時,將第一個元素放在結構體開辟空間的起始處,
1.2
其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處,
對齊數 = 編譯器默認的一個對齊數 與 該成員大小的較小值,
VS中默認的值為8
翻譯:
struct c { char a; int b; char c; };當存放int b時,需要先考慮b的大小size,再對比size和編譯器中默認對齊數的大小,取較小值作為該成員的對齊數,
此程式中size=4,默認對齊數為8,因此b的對齊數為4,
因此b需要對齊到4的整數倍的地址處,即:
c的對齊數為1,則:
1.3
結構體總大小為最大對齊數(每個成員變數都有一個對齊數)的整數倍,
翻譯:
本結構體的最大對齊數為b的對齊數4,則結構體大小應為4的倍數,但是到目前為止從a到c只使用了9個位元組的空間,因此還需要三個位元組,湊成12個位元組,才能成為4的倍數,
因此該結構體總大小為12,
1.4
如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整
體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍,
翻譯:
struct a { char a; int b; char c; } struct c { char a; int b; char c; struct a d; };在struct c中嵌套struct a,
struct a的最大對齊數為4,他的大小為12
struct c的大小必須是所有最大對齊數的整數倍,c的最大對齊數為4,目前大小為24,符合這一條件,則這一結構體大小為24,
2.存在原因:
2.1.平臺原因(移植原因):
不是所有的硬體平臺都能訪問任意地址上的任意資料的;某些硬體平臺只能在某些地址處取某些特
定型別的資料,否則拋出硬體例外,
比如某些硬體平臺在取結構體的整型值時,只能從4的倍數的地址值進行尋找,因此為了跨平臺需求,我們在編程時就要考慮到硬體的不同,多增加一些空間來滿足跨平臺應用需求,
2.2 性能原因:
資料結構(尤其是堆疊)應該盡可能地在自然邊界上對齊,
原因在于,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪
問,
比如說,在32位機器中,由于機器只有32根地址線,因此電腦一次最多可以讀取4個位元組的記憶體資訊,
現在我們創建一個結構體:
struct S { char c; int a; };如果說機器中不存在記憶體對齊,即我們將兩個資料連續存放,則它們在記憶體中的分布如下:
如果要讀取這兩個資料,c需要被讀取一次,a需要被讀取兩次,
現在我們將a對齊到4的倍數地址處:
此時c和a都只需被讀取一次即可,大大提高了機器的運行效率
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/402462.html
標籤:其他
上一篇:如何在aspnetcorewebAPI上正確地將串列轉換為IQueryable
下一篇:備戰藍橋 2021-12-31









