0

構造体へのポインターの配列があります。

item** items = NULL;

これらは、配列を割り当てて印刷するために私が書いた関数です。

void allocateItems(item** items, int numItems) {
    items =malloc(numItems*sizeof(item*));
    for (int i = 0; i < numItems; i++) {
        items[i]=malloc(sizeof(item*));
        items[i]->data = i + 1;
        items[i]->data2 = (i + 1) % 2;
    }
}

void printItems(item** items, int numItems) {
    for (int i = 0; i < numItems; i++) {
        printf("%d : %d\n", items[i]->data, items[i]->data2);
    }
}

しかし、その構造体の配列を印刷しようとすると、セグメンテーション違反が発生します。誰かが間違いを教えてもらえますか?

4

1 に答える 1

6

これは、次のものに十分なメモリを割り当てているだけですitem*:

items[i]=malloc(sizeof(item*));

にメモリを割り当てる必要がありitemます:

items[i]=malloc(sizeof(item));

で行われた変更をallocateItems()呼び出し元に表示するには、のアドレスをitems渡す必要があります。

allocateItems(&items, 4);

これは引数の型を変更しitems、関数内で逆参照する必要があることを意味します。

void allocateItems(item*** items, int numItems)
{
    *items = malloc(numItem * sizeof(item*));
    for (int i = 0; i < numItems; i++)
    {
        (*items)[i] = malloc(sizeof(item));
        (*items)[i]->data = i + 1;
        (*items)[i]->data2 = (i + 1) % 2;
    }
}

itemこれは、 の配列の代わりに の配列を割り当てることで簡略化できますitem*。また、配列内の各要素を割り当てるためitemsの倍数でフラグメント化されるのではなく、連続したメモリ ブロック内にのリストがあることも意味します。malloc()

void allocateItems(item** items, const int numItems)
{
    *items = malloc(numItems * sizeof(item));
    if (*items)
    {
        for (int i = 0; i < numItems; i++)
        {
            (*items)[i].data  = i + 1;
            (*items)[i].data2 = (i + 1) % 2;
        }
    }
}

item* items;
allocateItems(&items, 4);

if (items)
{
    for (int i = 0; i < 4; i++)
        printf("[%d]: (%d, %d)\n",
               i,
               items[i].data,
               items[i].data2);

    free(items);
}
于 2013-04-09T11:02:14.623 に答える