C++結構變數資料對齊問題

來源:互聯網
上載者:User

標籤:warning   命令   補齊   平台   tracking   imp   double   test   war   

為了避免混淆。做例如以下規定,下面代碼若不加特殊說明都執行於32位平台,結構體的預設對齊值是8,各資料類型所佔位元組數分別為

char佔一個位元組

int佔四個位元組

double佔八個位元組。

兩個範例

請問以下的結構體大小是多少?

struct Test{    char c ;    int i ;};

這個呢?

struct Test1{    int i ;    double d ;    char c ;};

在發布答案之前先看一下對齊的規則。

對齊規則

一般來說,結構體的對齊規則是先按資料類型自身進行對齊,然後再按整個結構體進行對齊。對齊值必須是2的冪。比方1,2。 4, 8。 16。

假設一個類型按n位元組對齊,那麼該類型的變數起始地址必須是n的倍數。

比方int按四位元組對齊,那麼int類型的變數起始地址一定是4的倍數。比方0x0012ff60。0x0012ff48等。

 

資料自身的對齊

資料自身的對齊值通常就是資料類型所佔的空間大小。比方int類型佔四個位元組,那麼它的對齊值就是4

整個結構體的對齊

整個結構體的對齊值通常是結構體中最大資料類型所佔的空間,比方以下這個結構體的對齊值就是8,由於double類型佔8個位元組。

struct Test2{    int i ;    double d ;};
範例答案

有了上面的基礎。再回過頭去看看一開始的兩個範例

先看結構體Test

1 c是char類型,按1個位元組對齊

2 i是int類型。按四個位元組對齊。所以在c和i之間實際上空了三個位元組。

整個結構體一共是1 + 3(補齊)+ 4 = 8位元組。

再看Test1

i是int類型。按4位元組對齊

d是double類型,按8位元組對齊,所以i和d之間空了4位元組

c是char類型。按1位元組對齊。

所以整個結構體是 4(i) + 4(補齊)+ 8(d) + 1(c) =  17位元組。注意!還沒完,整個結構體還沒有對齊。由於結構體中空間最大的類型是double。所以整個結構體按8位元組對齊,那麼終於結果就是17 + 7(補齊) = 24位元組。

書寫結構體的建議

我們對Test1做一點修改

struct Test1{    char c ;    int i ;    double d ;};

這時Test1的大小就變成了16,而不是24了,節省了8個位元組!

可見結構體中成員的書寫順序對結構體大小的影響還是非常大的。一個好的建議是,依照資料類型由小到大的順序進行書寫。

   

怎樣改動結構體的對齊值使用預先處理指令

#pragma pack(num)

num是結構體的對齊值,比方以下的範例按四個位元組對齊。

#pragma pack(4)

怎樣查看結構體的對齊值使用預先處理命令

#pragma pack(show)

該命令來查看當前的對齊值,可是要注意的是,結果是以warning的形式輸出的,所以要在VS的警告表單中才看得見。例如以下

warning C4810: value of pragma pack(show) == 8   

C++結構變數資料對齊問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.