1

柔軟な配列メンバーの例を読んで見ましたが、この可変長配列の要素を追加して読み取る方法が正確にはわかりません。

typedef struct School {
    char *name;
    char *courses[]; //Flexible Array Member
} School;

1) 誰かがこのフレキシブルな長さのメンバーに要素を追加し、保存後に印刷する方法の例を教えてください。

2)正しくmallocする方法も知りたいです。フレキシブル配列メンバーについて読んだことに基づいて、フレキシブル配列メンバー用にさらにスペースを追加する必要があり、単に使用することはできませんsizeof(School);。私の唯一の問題は、その柔軟なメンバーにどれだけ追加するかをどのように知るかです.

4

3 に答える 3

1

を変更しstructて、割り当てられた構造に存在するコースの数を追加する必要があります。

typedef struct School {
    char *name;
    int ncourses;
    char *courses[]; //Flexible Array Member
} School;

2 つの学校があり、1 つには 3 つのコースがあり、もう 1 つには 2 つのコースがあるとします。構造を次のように割り当てます。

School *mc = malloc(offsetof(struct School, courses) + 3 * sizeof(char *));
mc->name = strdup("Math College");
mc->ncourses = 3;
mc->courses[0] = strdup("Math 101");
mc->courses[1] = strdup("Math 102");
mc->courses[2] = strdup("Math 103");

School *ps = malloc(offsetof(struct School, courses) + 2 * sizeof(char *));
ps->name = strdup("Psycho School");
ps->ncourses = 2;
ps->courses[0] = strdup("Psycho 101");
ps->courses[1] = strdup("Unknown 404");

ご覧のとおり、変数配列の要素は、他の配列要素と同じようにアクセスされます。この呼び出しは、構造体の末尾にある構造malloc体メンバーと配列要素 (ここではポインター) に適切なサイズをバイト単位で割り当てます。char *

ジェネリック関数を使用して、そのような構造を割り当てて初期化できます。

School create_school(const char *school_name, int ncourses, char *courses[]) {
    School *sp = malloc(offsetof(struct School, courses) + ncourses * sizeof(char *));
    sp->name = strdup(school_name);
    sp->ncourses = ncourses;
    for (int i = 0; i < ncourses; i++) {
        sp->courses[i] = strdup(courses[i]);
    }
    return sp;
}
于 2016-01-24T01:30:07.257 に答える
0

基本的に、この手法は、構造体と最後の配列の要素に十分なメモリを動的に割り当てることです。

School *data = malloc(sizeof(*data) + number * sizeof(*(data->courses)));

for (i = 0; i < number; ++i)
{
     const char hello[] = "Hello";
     data->courses[i] = malloc(strlen(hello) + 1));   /* sizeof char is 1 by definition */
     strcpy(courses[i], hello);
}
于 2016-01-24T01:30:23.910 に答える
0

構造体に必要なサイズを計算するための正確な式は次のとおりです。

size_t need = offsetof(struct School, courses) + num_courses * sizeof(char *);

の使用に注意してくださいoffsetof。を使用する人もいますsizeofが、構造体のパディングによるメモリ オーバーヘッドが発生する可能性があります。

于 2016-01-24T00:40:59.563 に答える