今天在處理結構體物件的時候,發現自己一直以為的結構體物件的記憶體對齊只會在最後對齊是錯誤的理解,於是在知乎中看了
這篇回答後,把這種錯誤理解糾正了過來,現在就來寫個部落格記錄一下。
在c/c++中,結構體物件的大小不一定等於成員變數所佔的記憶體空間之和,這是由於記憶體對齊的存在,在計算結構體物件的大小時需要遵循以下三個原則所導致的:
1. 結構體變數的起始位址能夠被其最寬的成員大小整除
2. 結構體每個成員相對於起始位址的偏移能夠被其自身大小整除,如果不能則在前乙個成員後面補充位元組
3. 結構體總體大小能夠被最寬的成員的大小整除,如不能則在後面補充位元組
我們先來看第乙個例子
struct
第乙個例子的結構體物件的大小是多少個位元組呢?6個位元組?不對,是8個位元組。由於在上面的結構體當中,最寬的成員變數a占有了4個位元組,根據第三個原則:結構體總體大小能夠被最寬的成員的大小整除,如不能則在後面補充位元組,6%4 != 0,所以需要在結構體的最後補齊2個位元組,即8個位元組。
我們再來看看第二個例子
struct
這不是跟上面第乙個例子一模一樣嗎?只是成員變數的順序換了。那麼這個結構體物件的大小是多少個位元組呢?8個?不對,是12個。
由於在第二個例子的結構體中,第乙個是成員變數是char,第二個成員變數是int,所以根據第二個原則:結構體每個成員相對於起始位址的偏移能夠被其自身大小整除,如果不能則在前乙個成員後面補充位元組,1%4 !=0,char需要補充位元組到int,導致不是1+3,是4+4。最後呢根據第三個原則結構體總體大小能夠被最寬的成員的大小整除,如不能則在後面補充位元組,4+4+1=9,9%4 != 0,還需要在結構體的最後補齊3個位元組,即12個位元組。
好的,通過以上兩個例子,相信大家都學會了如何計算物件的大小了。
接下來通過**來驗證一下,並檢視結構體的記憶體分布,**如下
#include
#include
struct stest1
;struct stest2
;int
main()
當程式執行完stest1 *ptest1 = &test1;
語句時,結合std::cout
的輸出,我們可以知道,test1的記憶體分布如下圖所示
在執行完test1.c = 0;
語句時,test1的記憶體分布如下
在執行完memset(ptest1, 0, sizeof(stest1));
語句後,test1的記憶體分布如下
從上面就可以很清楚地看到,最後兩個位元組是stest1
結構體因記憶體補齊所增加的記憶體。
如何計算結構體的大小
運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...
如何計算結構體的大小
運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...
如何計算結構體的大小
運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...