2

ノードである構造体と、これらのノードのリストである別の構造体があります。リスト構造体では、ノードの配列ですが、配列ではなく、サイズが整数のポインターへのポインターです。

typedef struct node {
    struct node *next;
    MyDef *entry;
} Node;


typedef struct list {
    Node **table;
    int size;
} List;

List *initialize(void)
{
    List *l;
    Node **n;

    if ((l = (List *)malloc(sizeof(List))) == NULL)
        return NULL;
    l->size = 11;

    /* I think this is correctly allocating the memory for this 'array' of nodes */
    if ((n = (Node **)malloc(l->size * sizeof(Node))) == NULL)
        return NULL;

    /* Now, how do I set MyDef *entry and Node *next to NULL for each of the 'array'? */

    l->table = n;

    return l;
}

'配列'ごとにMyDef*entryとNode*nextをNULLに設定するにはどうすればよいですか?

4

2 に答える 2

1

(ノード**)はノードへの[配列]ポインターへのポインターであるため、割り当てる配列には構造体メンバーは含まれません。

(Node *)を使用すると、Node構造体の配列を指定するか、各ノードを個別に割り当ててから、それらへのポインターを配列に配置する必要があります。

あなたの場合の標準Cライブラリには関数calloc()があります:それは0で割り当てられた領域を初期化します(これは(char / short / int / long)0、0.0およびNULLに対応します)。

また、メモリリークがあります。

/* I think this is correctly allocating the memory for this 'array' of nodes */
if (... == NULL)
    return NULL;

配列の割り当てが失敗した場合、リストを解放しませんが、リストへのポインタを失います。次のように書き直します。

/* I think this is correctly allocating the memory for this 'array' of nodes */
if ((n = (Node **)malloc(l->size * sizeof(Node))) == NULL) {
    free(l);
    return NULL;
}

したがって、wievの観点からすると、正しいコードは次のようになります。

typedef struct node {
    struct node *next;
    MyDef *entry;
} Node;


typedef struct list {
    Node *table; /* (!) single asterisk */
    int size;
} List;

List *initialize(void)
{
    List *l;
    Node **n;

    if ((l = (MList *)malloc(sizeof(List))) == NULL)
        return NULL;
    l->size = 11;

    /* I think this is correctly allocating the memory for this 'array' of nodes */
    if ((n = (Node *)calloc(l->size, sizeof(Node))) == NULL)
    {
        free(l);
        return NULL;
    }

    /* Now, how do I set MyDef *entry and Node *next to NULL for each of the 'array'? */

    l->table = n;

    return l;
}

さらにC99を使用すると、可変サイズの構造体を作成できるため、次のような構造体を初期化できます。

typedef struct list {
    int size;
    Node table[0]
} List;

そして、malloc(sizeof(List)+ sizeof(Node)* n);を使用して、テーブルに必要な数のノードを割り当てます。

于 2010-10-26T11:48:22.790 に答える
0

まず第一に、配列を割り当てるコードにエラーがあるように思われます。ノードオブジェクトの配列ではなく、ポインタの配列をノードに割り当てるのsizeof(Node*)ではなく、言う必要があります。sizeof(Node)

次に、配列リストを反復処理できます。

for ( unsigned i = 0; i < l->size; ++i )
{
    Node* node = l->table[ i ];
    node->entry = NULL;
    node->next = NULL;
}

別のヒント:メモリリークの可能性に対して初期化関数を実際にチェックする必要があります。

于 2010-10-26T09:56:47.977 に答える