C 變數對齊

2021-06-20 16:54:06 字數 1544 閱讀 6300

編譯器要對c++**進行編譯時需要按照相應的型別為變數分配記憶體空間,最為人們熟知的就是那五個空間了:棧,堆,全域性資料區,常量區和**區。現在知道了哪些變數存放在哪些空間裡了,但是在相應的空間裡又是如何存放的呢?相信很多人都已經知道了,我也知道了。

對齊方式有三種規則,看網上已經很詳細了,我還是想用自己的話再說一遍吧:

1. 資料成員對齊規則:  為類,結構體或聯合體分配記憶體時,首先可以確定這些物件的首位址,類、結構體或聯合體的的成員變數在記憶體從相對於首位址的offset=0處開始分配記憶體,分配時遵循如下原則:比較這個變數的型別所佔位元組數m和#paragma pack(n)中指定的n的大小。求得較小值,變數偏移應該為該值的整數倍。

2. 結構(或聯合)的整體對齊規則:  在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。 

3. 含有物件組合的對齊規則:各個基本型別成員的對齊方式是不變的,遇到物件的情況下,要在符合這個物件中各個資料型別的位元組數的公倍數進行對齊,否則,可能會導致物件內部不對齊。 

下面用網上的例子和我的改進加以說明試驗:通過#pragma pack(n)改變「對齊係數」,然後察看sizeof(struct test_t)的值。

1位元組對齊(#pragma pack(1))

輸出結果:sizeof(struct test_t) = 8

分析過程:

1) 成員資料對齊

#pragma pack(1)

struct test_t ;

#pragma pack()

成員總大小=8

2) 整體對齊

整體對齊係數 = min((max(int,short,char), 1) = 1

整體大小(size)=$(成員總大小) 按 $(整體對齊係數) 圓整 = 8 /* 8%1=0 */ [注1]

2位元組對齊(#pragma pack(2))

輸出結果:sizeof(struct test_t) = 10

分析過程:

1) 成員資料對齊

#pragma pack(2)

struct test_t ;

#pragma pack()

成員總大小=9

2) 整體對齊

整體對齊係數 = min((max(int,short,char), 2) = 2

整體大小(size)=$(成員總大小) 按 $(整體對齊係數) 圓整 = 10 /* 10%2=0 */

4位元組對齊(#pragma pack(4))

輸出結果:sizeof(struct test_t) = 12

分析過程:

1) 成員資料對齊

#pragma pack(4)

struct test_t ;

#pragma pack()

成員總大小=9

2) 整體對齊

整體對齊係數 = min((max(int,short,char), 4) = 4

整體大小(size)=$(成員總大小) 按 $(整體對齊係數) 圓整 = 12 /* 12%4=0 */

C 結構變數資料對齊問題

為了避免混淆,做如下規定,以下 若不加特殊說明都執行於32位平台,結構體的預設對齊值是8,各資料型別所佔位元組數分別為 char佔乙個位元組 int佔四個位元組 double佔八個位元組。請問下面的結構體大小是多少?struct test 這個呢?struct test1 在公布答案之前先看一下對齊...

C 結構變數資料對齊問題

為了避免混淆。做例如以下規定,下面 若不加特殊說明都執行於32位平台,結構體的預設對齊值是8,各資料型別所佔位元組數分別為 char佔乙個位元組 int佔四個位元組 double佔八個位元組。請問以下的結構體大小是多少?struct test 這個呢?struct test1 在發布答案之前先看一下...

記憶體變數邊界對齊

一 什麼是記憶體對齊 a 編譯器按照成員列表的順序給每個成員分配記憶體.b 當成員需要滿足正確的邊界對齊時,成員之間用額外位元組填充.c 結構體的首位址必須滿足結構體中邊界要求最為嚴格的資料型別所要求的位址.d 結構體的大小為其最寬基本型別的整數倍.1 include2 3 include4 5 i...