在c語言和c++語言中相信很多人都有使用過sizeof(),這個帖子主要偏向於交流獲取class和struct的位元組數時候的問題。
我使用的是windows 7的32位os 和 vs2010的旗艦版
先來一些正常的
[cpp]view plain
copy
struct
tests
; class
testc
};
intmain()
這個時候相信大家都能想到輸出的結果是
從這裡我們可以看到我們用sizeof()取struct和class的位元組的時候只有他們的成員變數才算進去的,方法及其內部的變數是不算的。當然了,乙個空類是預設1位元組的。
接下來我們來做一些「不正常」的
[cpp]view plain
copy
struct
tests
; class
testc
};
intmain()
我們這次只是調換了一下成員變數的位置,然後我們再次執行一下檢視結果。
很奇怪的結果,這個的執行結果不是我們正常想象的結果。這是為什麼呢?
原來struct和class中為變數分配空間是以結構中最長資料元素為對齊方式的。
例如之前我們看過的例子(class 和 struct一樣我們就以struct為例):
tests 一:
變數 分配空間(位元組) 占用空間(位元組) 起始位址
bool a 4 1 1
char b 0 1 2
short c 0 2 3
int d 4 4 5
通過這個我們可以看到分配空間是以最高的int為主的,如果可以填充的話就填充。sizeof(tests) = 8
tests 二:
變數 分配空間(位元組) 占用空間(位元組) 起始位址
char b 4 1 1
short c 0 2 2
int d 4 4 5
bool a 4 1 9
比之前我們只是將變數a調換到了最後,但是整個空間分配就和之前的不一樣了。sizeof(tests) = 12
通過這兩次的圖表對比大家可以了解是什麼原因導致這個結果了吧。。
記憶體對齊的規則:
1、 對於結構的各個成員,第乙個成員位於偏移為0的位置,以後每個資料成員的偏移量必須是min(#pragma pack()指定的數,這個資料成員的自身長度) 的倍數。
2、 在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行對齊。
#pragma pack(n) 表示設定為n位元組對齊。 vc6預設8位元組對齊
在判斷如何對齊的時候,我們可以根據偏移量和自身型別的sizeof的倍數來決定例如:
[cpp]view plain
copy
struct
tests
;
在給char b申請記憶體時偏移量為0,是sizeof(char)的倍數直接分配。
在給int c申請記憶體時偏移量為1,不是sizeof(int)的倍數所以要填充3個位元組讓偏移量達到4成為sizeof(int)的倍數然後為其分配記憶體。
在給double d申請記憶體時偏移量為8時sizeof(double)的倍數,直接分配。
所以最後sizeof(tests)的結果是16
[cpp]view plain
copy
struct
tests
;
在tests中按照上面描述的方法進行分配記憶體。
分配int c時偏移量為0直接分配
分配char b時偏移量為4直接分配
那麼sizeof(tests)就是5了嗎? 結果顯然不是的··········
這只是完成了資料成員的記憶體對齊,還沒有做結構本身的記憶體對齊。按照結構本身的對齊規則來說,我們要取出所有成員和#pragma pack指定的數值中較小的乙個得倍數來對齊結構。所以sizeof(tests)的結果是8
C 記憶體對齊
vc6.0編譯器對記憶體對齊的管理方式遵循以下兩個原則 1.對於結構體內部變數的對齊方式 變數存放的起始位址相對於結構的起始位址的偏移量 char 偏移量必須為sizeof char 即1的倍數 int 偏移量必須為sizeof int 即4的倍數 float 偏移量必須為sizeof float ...
c 記憶體對齊
一.計算struct的size有兩個原則 pragma pack n n是編譯器的對齊位元組數 1 struct中各成員按照對齊原則 在為當前變數 設為a 分配記憶體時,要參考之前所有變數的偏移量之和 設為d d必須是min n,sizeof a 的倍數,否則編譯器會自動在最後補上缺少的位元組數。2...
C 記憶體對齊
c 中的記憶體對齊 記憶體對齊 在我們的程式中,資料結構還有變數等等都需要占有記憶體,在很多系統中,它都要求記憶體分配的時候要對齊,這樣做的好處就是可以提高訪問記憶體的速度。我們還是先來看一段簡單的程式 程式一 1 include 2 using namespace std 3 4structx1 ...