私の好奇心のために、私の構造体の各バイトを表示するプログラムを作成しました。ここでは、コードは次のようになります。64ビットマシン上のメモリ内の構造体表現
#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
そして、ここでは質問です: sizeof(long long int) is 8
あれば、なぜsizeof(serialize_test_t) is 24
の代わりに、32 - 私は常に構造体の大きさがあると思いました例えば、8(バイト)* 4(フィールド)= 32(バイト) - デフォルトでは、プラグマパックのディレクティブはありません。
また、構造体をchar *
にキャストすると、メモリからの値のオフセットが8バイトではないことが出力からわかります。私に手がかりを与えることができますか?または、これはコンパイラの最適化の一部ですか?
あなたの前提は間違っています。スタンダードはパッキングやパッディングについては、それ以外には何も言わない。 –
パッディング要件はCやアーチ依存ではありませんが、ABIに依存すると、x86_64 ABIに固有の回答が得られる可能性があります.2つの主要なもの、win64とSystem V(その他すべて)はかなり似ています。 –
標準では、構造体のパディングに関する1つのことが述べられています。構造体の最初の要素の前には何も存在しません。パディングがあるかどうかと、それが最初の要素の前のものと異なるかどうかはコンパイラによって異なります。しかし、構造体型 'struct X x;'の場合、 'x'のアドレスは' x'の最初の要素のアドレスでもあります(ただし、アドレス型は異なります)。 –