简体   繁体   中英

Why sizeof() differs on 64bit cpu?

Consider following example:

#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;
}

Output is:

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

Why are they differ on 64bit machine ? On 32 bit platform results are the same:

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

Some diagrams to help you see:

32-bit:

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

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

64-bit:

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

+---------+---------+---------+---------+---------+---------+
| i1 | i2 | i3 | i4 | i5 | i6 | i7 |~~~~|   i8    |   i9    | Struct B
+---------+---------+---------+---------+---------+---------+
  • + : address boundaries
  • ~ : padding

The compiler aligns the struct members by a boundary (which is different in your compilation attempts).

Add a

#pragma pack (1)

directive at the beginning of source file and retry.

Because it can. The compiler isn't required to use the same layout between 32 and 64-bit mode. It can insert padding when it wants to. You shouldn't rely on the precise layout of the struct in the first place.

In principle, it could even change the padding each time you compile. (It's hard to imagine why the compiler would do this, but it's allowed to)

64-bit integers have to be placed on a 64-bit memory boundary. Thus, when creating a struct A on a 64-bit machine, the compiler sticks a 4-byte padding space after i3 and i7 - thus putting an extra 8 bytes in there.

由于元素之间的填充。

This is caused due to structure aligning: struct A has 3 32 bit values followed by a 64bit one. Regardless of the packing of the first 3 elements the 64bit element definitely won't start between boundaries (ie taking up half of two separate 64bit values) on 64bit, so there is at least a 32bit padding between the 3rd and 4th element.

sizeof(b)是48,因为最后一个uint32占用了一个完整的64位(因为后续的uint64s与64位块对齐.sizeof(a)占用更多因为前3个unit32s占用2个块,接下来的3个占用2个块,最后的uint32占用一个完整的64位块

This is because of aligning.

It is possible that 64bit integers on your platform are required to be 64bit aligned.

So In the mixed structure you have 3 32 bit integer, after them there must be inserted an other 32bit padding to have the 64bit integer correctly aligned.

The size difference should vanish if you insert and even number of 32bit field before your 64 bit field.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM