たとえば、C で構造体を作成する場合:
typedef struct student
{
int roll_no;
char* name;
int* pointer;
}student;
roll_no と name がメモリに連続して格納されていないことに気付きました。これはどのように作動しますか?このデータをカプセル化することが目的である場合、それらが連続して格納された方がよいのではないでしょうか? コンパイラは、これらのデータが一緒に属していることをどのように認識しますか?
たとえば、C で構造体を作成する場合:
typedef struct student
{
int roll_no;
char* name;
int* pointer;
}student;
roll_no と name がメモリに連続して格納されていないことに気付きました。これはどのように作動しますか?このデータをカプセル化することが目的である場合、それらが連続して格納された方がよいのではないでしょうか? コンパイラは、これらのデータが一緒に属していることをどのように認識しますか?
コンパイラは、アーキテクチャの要件に合わせて構造体の各要素の開始位置を揃えます。これは通常、アラインメントが単語境界上にあることを意味しますが、厳密で迅速なルールはありません。
typedef はアラインメントには影響しません。構造体などのオブジェクトへの「簡略参照」を作成するだけです。typedef はシノニムと考えることができます。
はname実際には一緒に保存されません。それへのポインタstructのみが保存されます。データは通常、それ自体の外側の領域に動的に割り当てられます。struct
名前を一緒に保存するには、structそれを配列にする必要があります。このアプローチの欠点は、文字列が固定長でなければならない (つまり、すべての が最大長の にstruct十分な量のメモリを割り当てるか、.この最後のアプローチの欠点は、(1) 割り当てが非常に複雑になること、(2) そのようなの配列を作成できないこと、(3) 構造体に柔軟な配列を 1 つしか持てないことです。namename[]structstruct
それらは連続して格納されます。char *name 内に含まれるアドレスが別の場所にあるというだけです。メモリに連続して格納するには、ポインターの代わりに配列を使用します。
これはメモリに格納される方法です。たとえば、構造体のアドレスは 1000 (10 進数) から始まります。
1000 roll_no
1004 name
1008 pointer
name と pointer はポインターなので、malloc によって割り当てられた値 (アドレス) を保持します。
s->name = malloc(100);
s->pointer = malloc(4);
この場合、構造体のパディングはありません。これは、すべてが int であるため (ポインターでさえも)、アーキテクチャのレジスタ サイズ (通常は 32 ビットまたは 64 ビット) のサイズであることを意味します。
データは連続して格納されますが、最適化と単語境界への配置により、全体が存在する場合があります。アライメントは、実行しているプロセッサと選択したコンパイラ オプションによって異なります。(梱包)
コンパイラは構造体へのオフセットを計算するため、メモリを参照して構造体の要素を取得できます。
実際には構造体で
struct student
{
int roll_no;
char* name;
int* pointer;
}
Cはあなたが望むことを正確に行います(「構造パディング」以外に、これは別の話です)。Intel プロセッサを想定するとgcc、構造体は
int、その後に続くchar *ポインターと、それに続くint *ポインターへのポインターの 4 バイトnameメンバは char(s) へのポインタであり、通常はメモリ内のどこかにある文字列へのポインタです。例えば
char *string = "John Doe";
int value = 255;
struct student me;
me.roll_no = 15;
me.name = string;
me.pointer = &value;
ここで文字列はメモリのどこかにあります - お気づきのように、構造体よりもずっと前に宣言されています。そのメモリ位置が0x12345678で、値が で0x20000000、構造が 0x22222222 であるとします。
0x12345678 : John Doe\0
...
0x20000000 : FF000000 // 255
...
0x22222222 : 0F0000001234567820000000
、文字列アドレス、および値アドレスの構造が表示0F000000されます。151234567820000000