1

次のようにリストを初期化する場合、この構造の要素にアクセスするにはどうすればよいですか。

group **list = (group **) malloc(sizeof(group)); 

typedef struct
{
    // ID of the group, 'A' to 'D'
    char id;

    // a list of members in the group 
    char **members;
} group;

使用(*list)->id = 'A'してみましたが、コンパイルされますが、プログラムの実行時にセグメンテーション違反エラーが発生します。

4

4 に答える 4

5
struct group
{
    // ID of the group, 'A' to 'D'
    char id;

    // a list of members in the group 
    char **members;
};

//this initializes one group
group *a_group = malloc(sizeof(struct group)); //cast not needed in C

//this initializes an array of 10 group
group **list = malloc(sizeof(struct group *) * 10);

//initialize each one of the 10
for(int i = 0; i < 10; ++i){
  list[i] = malloc(sizeof(struct group));
}

//get something out of group
a_group->id;

//get first group out of list
list[0]->id;
*list->id;

// 10 elements continuous memory
group *array_of_groups = malloc(sizeof(struct group) * 10);
array_of_groups[0].id;
*array_of_groups.id;
于 2012-07-16T14:40:09.120 に答える
4

正常にコンパイルされますが、メモリが正しく割り当てられていません。

にメモリを割り当てましたgroup **list。これは、最終的にはstructへのポインタの配列になりますgroup。あなたがやろうとしていたことは次のとおりです。

group** list = malloc(sizeof(group*) * 5);  // e.g. 5 pointers

次に、配列内のポインタごとに、独自のメモリを割り当てます。

int i;
for (i = 0; i < 5; i++) {
    list[i] = malloc(sizeof(group));
}

たとえばid、2番目の構造体でアクセスするには、次のようにします。

list[1]->id = 'A';

最初の*list構造体にアクセスすることに注意してください。これは。と同等です。list[0]

補足:
2つのレベルの間接参照により、構造体を非連続的にメモリに格納できます。または、1レベルの間接参照を使用して、それらを継続的に保存することもできます。

group list* = malloc(sizeof(group) * 5);  // Again, 5 structs

次に、次のコマンドでメンバーにアクセスします。

list[0].id = 'A';
于 2012-07-16T14:54:58.147 に答える
2

二重間接ポインターは、デフォルトで最初のエントリを指しているリストへの単なるポインターであることに注意してください。リストポインタ(** list)だけでなく、個々のエントリに割り当てる必要があります。次のようなものがあります。

//rough code, not tested... std caveats apply :)
group *one_group = malloc(sizeof(group));

list[0]=one_group;
list[0]->id = 'A'; // or one_group->id='A'; 
于 2012-07-16T14:47:17.977 に答える
-1

ポインタのリストを作成する必要があるとしましょう。このリストのメンバーはそれぞれ、タイプグループによってマップされたメモリチャンクを指します。

今、私は10個のアイテムを持っているとしましょう、

それで:

group *tmp = malloc(sizeof(group) * 10);

現在、tmpはこれらのチャンクの開始を指しています。

ここで、ポインターのリストを作成します。リスト内のすべての項目がチャンクを指します。

10個のポインタを作成しましょう。

group ** list = malloc(sizeof(group *) * 10)

次に、このポインタのリストを初期化します。

i = 10;
while(i--) {
    list++ = &(tmp++);
}

これで、リストはチャンクへのポインターで初期化されます。1つの問題が残っています、あなたのリストは最後を指しています。あなたがそれを望まないなら

list-= 10;

ここで、リストから何かを取得したいとします。

while(i--) {
    printf("%c\n", (*(list++))->a);
}

しかし、この種のリスト管理は奇妙であり、エラーが発生しやすいことは言うまでもありません。あなたは「リンクリスト」を通してあなたのリストを維持することを真剣に考えるべきです。あなたが与えたような些細なシナリオは、単一リンクリストを介して簡単に実装できます。

于 2012-07-16T14:59:21.720 に答える