07-STM32MP1結構體在內存中的存儲規則

一個結構體變量定義完之後,其在內存中的存儲並不等於其所包含元素的寬度之和。

例一:

#include <iostream>
using namespace std;
 
struct X {
	char a;
	int b;
	double c;
 }S1;
 
int main() {
 
	cout << sizeof(S1) << endl;
	cout << sizeof(S1.a) << endl;
	cout << sizeof(S1.b) << endl;
	cout << sizeof(S1.c) << endl;
 
	return 0;
}

在例一中的結構體變量S1定義之後,經測試,會發現sizeof(S1)= 16,其值不等於sizeof(S1.a) = 1、sizeof(S1.b) = 4和 sizeof(S1.c) = 8三者之和,這裏面就存在存儲對齊問題。

原則一:結構體中元素是按照定義順序一個一個放到內存中去的,但並不是緊密排列的。從結構體存儲的首地址開始,每一個元素放置到內存中時,它都會認爲內存是以它自己的大小來劃分的,因此元素放置的位置一定會在自己寬度的整數倍上開始(以結構體變量首地址爲0計算)。

比如此例,首先系統會將字符型變量a存入第0個字節(相對地址,指內存開闢的首地址);然後在存放整形變量b時,會以4個字節爲單位進行存儲,由於第一個四字節模塊已有數據,因此它會存入第二個四字節模塊,也就是存入到4~8字節;同理,存放雙精度實型變量c時,由於其寬度爲8,其存放時會以8個字節爲單位存儲,也就是會找到第一個空的且是8的整數倍的位置開始存儲,此例中,此例中,由於頭一個8字節模塊已被佔用,所以將c存入第二個8字節模塊。

考慮另外一個實例:

struct X {
	char a;
	double c;
	int b;
 }S2;

在例二中僅僅是將double型的變量和int型的變量互換了位置。測試程序不變,測試結果卻截然不同,sizeof(S2)=24,不同於我們按照原則一計算出的8+8+4=20,這就引出了我們的第二原則。

原則二:在經過第一原則分析後,檢查計算出的存儲單元是否爲所有元素中最寬的元素的長度的整數倍,是,則結束;若不是,則補齊爲它的整數倍。

例二中,我們分析完後的存儲長度爲20字節,不是最寬元素長度8的整數倍,因此將它補齊到8的整數倍,也就是24。這樣就沒問題了。

 掌握了這兩個原則,就能夠分析所有數據存儲對齊問題了。

注意:

可以通過memcmp()來比較2個相同的結構體變量是否相等,但這2個變量必須在賦值前進行清零初始化(否則結果不準確) ,或者二者是通過直接對等賦值而來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章