6

好奇心のために、構造体の各バイトを表示するプログラムを作成しました。コードは次のとおりです。

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

出力は次のとおりです。

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

そしてここに質問があります: ifsizeof(long long int) is 8の場合、なぜsizeof(serialize_test_t) is 2432 ではなく - 構造体のサイズは最大の型に丸められ、次のようにフィールドの数で乗算されると常に考えていました: 8(バイト)*4(フィールド) = 32(バイト) ) — デフォルトでは、pragma pack ディレクティブはありませんか?

また、その構造体をキャストするとchar *、メモリ内の値間のオフセットが 8 バイトではないことが出力からわかります。手がかりを教えてもらえますか?それとも、これは単なるコンパイラの最適化ですか?

4

5 に答える 5

0

パディングは通常、構造体がワード サイズ (この場合は 8) の倍数になるように追加されます。

したがって、最初の 2 つのフィールドは 1 つの 8 バイト チャンクにあります。3 番目のフィールドは別の 8 バイト チャンクにあり、最後のフィールドは 1 つの 8 バイト チャンクにあります。合計 24 バイト。

char 
padding
padding
padding
unsigned int
unsigned int
unsigned int
unsigned int
char                            // Word Boundary
padding
padding
padding
padding
padding
padding
padding
unsigned long long int           // Word Boundary
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
于 2013-05-15T13:42:43.127 に答える
0

アライメントと関係があります。

構造体のサイズは、最大の型に丸められず、フィールドで乗算されます。バイトは、それぞれのタイプごとに整列されます: http://en.wikipedia.org/wiki/Data_structure_alignment#Architectures

アライメントは、型がそのサイズの倍数であるメモリアドレスに出現する必要があるという点で機能します。したがって、次のようになります。

Char は 1 バイトでアラインされているため、1 の倍数であるメモリ内の任意の場所 (任意の場所) に表示できます。

unsigned int は、4 の倍数のアドレスで開始する必要があります。

char はどこでもかまいません。

long long は 8 の倍数である必要があります。

アドレスを見てみると、こんな感じ。

于 2013-05-15T13:45:21.953 に答える