在項目開發中,很多時候其實會有用到sizeof一個結構體,具體什么時候用到呢。
比如說有這樣一個結構體:
~~~
typedef struct tagOutCard
{
short UserId; // 用戶ID
int byCardCount; // 出牌數目
int byCardData[20]; // 撲克列表
}ST_OUT_CARD;
~~~
這是一個棋牌游戲中玩家出牌的數據包,需要將它賦值之后發送到服務器。
那么就會用到sizeof(ST_OUT_CARD)。
那到底這個ST_OUT_CARD是多大呢?
下面來說說怎么計算這個東西。
因為計算機為了加快讀寫數據的速度,編譯器就實現了數據對齊的做法來為每一個結構體分配空間。這里就涉及到一個內存對齊的計算了。
下面用一個直觀一點的結構體來示例計算:
~~~
typedef struct Data
{
char a; // 1 // 會擴展到4
float b; // 4
double c; // 8
long long d; // 8
long double e; // 8
long f; // 4
short g; // 2 // 會擴展到4
int h; // 4
bool i; // 1
}ST_DATA; // 最后結構體會是8的倍數
~~~
有這樣一個包含了基本類型的Data結構體。
要想sizeof(ST_DATA)求得大小就要看內存分配了,下面就是計算這個結構體大小的過程:
按照自上向下的為結構體分配空間,并在它們之間作調整。首先為char分配一個空間,接著編譯器為了實現數據的對齊,在分配float的時候會對之前所分配的空間進行一些調整,調整方式是按照原先分配的空間的大小和當前要分配的大小來決定將要分配的空間,因為float為4字節(可以自己sizeof(float)來看),所以編譯器要求在float之前所分配的空間大小應該是當期要分配的空間的倍數,在這里也就是說在float前面分配的應該是4的倍數空間才行,所以原來的char被迫擴展到4個字節,然后才為float分配4個字節,這樣這兩個變量就占了8字節。由于double類型的數據占8個字節,是4的倍數,所以就直接相加。
現在就是a(4)+b(4)+c(8)+d(8)+e(8) +f(4)= 36。在int這個類型的時候這里也會是將short類型的內存字節擴展到4。
所以到最后的時候就是36+g(4)+h(4)+i(1) = 45。
以為這里就是對齊好了嗎?sizeof出來就是45了嗎?
其實還有一個就是編譯器對結構體整體的一個倍數處理,已經為結構體分配好45個字節空間,那么接下來就是編譯器要求整個結構體所分配的空間大小是結構體中占用空間最多的類型所占用空間大小的倍數。
如上面的例子,結構體中占用空間最多的就是8個字節的數據類型,那么就要求結構體總大小是這個類型的倍數,在這里也就是要求結構體所占用空間大小要是8 的倍數,因為45不是8的倍數,所以結構體被迫擴展自己的空間,以滿足需要,所以就擴展到48個字節。
所以sizeof(ST_DATA)的結果是48,就是這樣計算出來的。
- 前言
- C++讀取配置文件
- 結構體內存對齊后所占內存空間大小的計算
- do{}while(0)的妙用
- Cocos2dx實現翻牌效果(CCScaleTo與CCOrbitCamera兩種方式)
- C++的error LNK2019: 無法解析的外部符號編譯錯誤
- Java使用JNI調用C++的完整流程
- strupr與strlwr函數的實現
- strcat函數實現
- Windows上VS使用pthread重溫經典多線程賣票(pthreads-w32-2-8-0-release.exe)(windows上使用pthread.h)
- pthread的pthread_join()函數理解實驗
- 順序存儲結構和鏈式存儲結構的選擇
- C語言冒泡排序
- VS看反匯編、寄存器、內存、堆棧調用來學習程序設計
- 快速排序
- C++的構造函數初始化列表
- fatal error C1083: 無法打開包括文件: “SDKDDKVer.h”: No such file or directory
- C++實現簡單的String類