乙個結構體變數定義完之後,其在記憶體中的儲存並不等於其所包含元素的寬度之和。
例一:
#include using namespace std;
struct x s1;
int main()
在例一中的結構體變數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 s2;
在例二中僅僅是將double型的變數和int型的變數互換了位置。測試程式不變,測試結果卻截然不同,sizeof(s2)=24,不同於我們按照原則一計算出的8+8+4=20,這就引出了我們的第二原則。
原則二:在經過第一原則分析後,檢查計算出的儲存單元是否為所有元素中最寬的元素的長度的整數倍,是,則結束;若不是,則補齊為它的整數倍。
例二中,我們分析完後的儲存長度為20位元組,不是最寬元素長度8的整數倍,因此將它補齊到8的整數倍,也就是24。這樣就沒問題了。
掌握了這兩個原則,就能夠分析所有資料儲存對齊問題了。
注意:可以通過memcmp()來比較2個相同的結構體變數是否相等,但這2個變數必須在賦值前進行清零初始化(否則結果不準確) ,或者二者是通過直接對等賦值而來。
結構體在記憶體中對齊
剛剛完成乙個檔案的遷移程式,其中遇到了結構體對齊的問題,所以拿出來說說,與各位博友們分享。我的程式很簡單,就是把之前通過乙個結構體 fwrite 到檔案 a 裡的內容讀出,然後轉給另乙個結構體儲存。程式是簡單,但我擔心的是之前把結構體 fwrite 到檔案 a 的程式對齊結構體規則是怎樣的?一定要知...
float,double在記憶體中的儲存方式
將17.625換算成 float型。首先,將17.625換算成二進位制位 10001.101 0.625 0.5 0.125,0.5即 1 2,0.125即 1 8 如果不會將小數部分轉換成二進位制,請參考其他書籍。再將 10001.101 向右移,直到小數點前只剩一位 成了 1.0001101 x...
資料在記憶體中的儲存方式
之前在面試的時候有遇到乙個面試題 記憶體中的顯示 輸入出其實這就是little endian 小端序列 的儲存形式 比方說我有乙個0xa5b1的乙個資料。如果當前的機器是小端序列那麼在 記憶體中高位位址 存放的就是a5 example 0x40000001 記憶體中低位位址 存放的就是b1 exam...