簡體   English   中英

為什么sizeof()在64位cpu上有所不同?

[英]Why sizeof() differs on 64bit cpu?

考慮以下示例:

#include <stdio.h>
#include <inttypes.h>

struct A {
        uint32_t i1;
        uint32_t i2;
        uint32_t i3;
        uint64_t i4;
        uint32_t i5;
        uint32_t i6;
        uint32_t i7;
        uint64_t i8;
        uint32_t i9;
};

struct B {
        uint32_t i1;
        uint32_t i2;
        uint32_t i3;
        uint32_t i4;
        uint32_t i5;
        uint32_t i6;
        uint32_t i7;
        uint64_t i8;
        uint64_t i9;
};

int
main()
{
        struct A a;
        struct B b;

        printf("sizeof(a) = %u, sizeof(b) = %u\n", sizeof(a), sizeof(b));

        return 0;
}

輸出是:

$ ./t2 
sizeof(a) = 56, sizeof(b) = 48
$ 

他們為什么在64位機器上有所不同? 在32位平台上的結果是相同的:

$ ./t2
sizeof(a) = 44, sizeof(b) = 44

一些圖表可以幫助您了解:

32位:

+----+----+----+----+----+----+----+----+----+----+----+
| i1 | i2 | i3 |   i4    | i5 | i6 | i7 |   i8    | i9 | Struct A
+----+----+----+----+----+----+----+----+----+----+----+

+----+----+----+----+----+----+----+----+----+----+----+
| i1 | i2 | i3 | i4 | i5 | i6 | i7 |   i8    |   i9    | Struct B
+----+----+----+----+----+----+----+----+----+----+----+

64位:

+---------+---------+---------+---------+---------+---------+---------+
| i1 | i2 | i3 |~~~~|    i4   | i5 | i6 | i7 |~~~~|   i8    | i9 |~~~~| Struct A
+---------+---------+---------+---------+---------+---------+---------+

+---------+---------+---------+---------+---------+---------+
| i1 | i2 | i3 | i4 | i5 | i6 | i7 |~~~~|   i8    |   i9    | Struct B
+---------+---------+---------+---------+---------+---------+
  • + :地址邊界
  • :填充

編譯器通過邊界(在編譯嘗試中不同)對齊struct成員。

添加一個

#pragma pack (1)

指令在源文件的開頭並重試。

因為它可以。 編譯器不需要在32位和64位模式之間使用相同的布局。 它可以在需要時插入填充。 您不應該首先依賴結構的精確布局。

原則上,它甚至可以在每次編譯時更改填充。 (很難想象為什么編譯器會這樣做,但它被允許)

必須將64位整數放在64位存儲器邊界上。 因此,當在64位機器上創建結構A時,編譯器在i3和i7之后粘貼一個4字節的填充空間 - 因此在那里增加了8個字節。

由於元素之間的填充。

這是由於結構對齊引起的: struct A有3個32位值,后跟64位值。 無論前3個元素的打包如何,64位元素肯定不會在64位之間的邊界之間開始(即占據兩個獨立的64位值的一半),因此在第3和第4個元素之間至少有32位填充。

sizeof(b)是48,因為最后一個uint32占用了一個完整的64位(因為后續的uint64s與64位塊對齊.sizeof(a)占用更多因為前3個unit32s占用2個塊,接下來的3個占用2個塊,最后的uint32占用一個完整的64位塊

這是因為對齊。

您的平台上的64位整數可能需要64位對齊。

所以在混合結構中你有3個32位整數,在它們之后必須插入另一個32位填充以使64位整數正確對齊。

如果在64位字段之前插入偶數32位字段,則大小差異應該消失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM