在64位机器上的内存中的结构表示

Jos*_*siP 6 c

为了我的好奇心,我编写了一个程序来显示我的结构的每个字节.这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>

#define MAX_INT 2147483647
#define MAX_LONG 9223372036854775807

typedef struct _serialize_test{
   char a;
   unsigned int b;
   char ab;
   unsigned long long int c;
}serialize_test_t;


int main(int argc, char**argv){
   serialize_test_t *t;
   t = malloc(sizeof(serialize_test_t));
   t->a = 'A';
   t->ab = 'N';
   t->b = MAX_INT;
   t->c = MAX_LONG;

   printf("%x %x %x %x %d %d\n", t->a, t->b, t->ab, t->c, sizeof(serialize_test_t), sizeof(unsigned long long int));

   char *ptr = (char *)t;

   int i;
   for (i=0; i < sizeof(serialize_test_t) - 1; i++){
      printf("%x = %x\n", ptr + i, *(ptr + i));
   }

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

41 7fffffff 4e ffffffff 24 8
26b2010 = 41
26b2011 = 0
26b2012 = 0
26b2013 = 0
26b2014 = ffffffff
26b2015 = ffffffff
26b2016 = ffffffff
26b2017 = 7f
26b2018 = 4e
26b2019 = 0
26b201a = 0
26b201b = 0
26b201c = 0
26b201d = 0
26b201e = 0
26b201f = 0
26b2020 = ffffffff
26b2021 = ffffffff
26b2022 = ffffffff
26b2023 = ffffffff
26b2024 = ffffffff
26b2025 = ffffffff
26b2026 = ffffffff
Run Code Online (Sandbox Code Playgroud)

这里有一个问题:if sizeof(long long int) is 8,那么为什么sizeof(serialize_test_t) is 24而不是32 - 我总是认为struct的大小舍入到最大类型并乘以像这里的字段数例如:8(字节)*4(字段)= 32(字节) ) - 默认情况下,没有pragma pack指令?

此外,当我转换结构时,char *我可以从输出中看到内存中值之间的偏移量不是8个字节.你能给我一个线索吗?或许这只是一些编译器优化?

Day*_*rai 4

在像 SPARC 或 Intel [34]86 这样的现代 32 位机器上,或者从 68020 开始的任何 Motorola 芯片上,每个数据项通常必须“自对齐”,从一个地址的倍数开始。类型大小。因此,32 位类型必须在 32 位边界上开始,16 位类型必须在 16 位边界上开始,8 位类型可以在任何位置开始,struct/array/union 类型具有其最严格成员的对齐方式。

结构的总大小将取决于包装。在您的情况下,它将为 8 字节,因此最终结构将如下所示

typedef struct _serialize_test{

   char a;//size 1 byte

   padding for 3 Byte;

   unsigned int b;//size 4 Byte

   char ab;//size 1 Byte again

   padding of 7 byte;

   unsigned long long int c;//size 8 byte

}serialize_test_t;
Run Code Online (Sandbox Code Playgroud)

这样前两个和后两个就正确对齐了,总大小达到 24。