-1

これはばかげた質問かもしれません。同様の質問が寄せられているのを目にしますが、答えが得られません。次のコードが生成するのはなぜですか:

エラー: タイプ 'struct node_t *' からタイプ 'node_t' に代入するときに互換性のないタイプです</p>

node_t list_array[10];
typedef struct node
{
    int value;
    struct node *next;
    struct node *prev;
} node_t;

node_t* create_node(void)
{
    node_t *np;
    np->next = NULL;
    np->prev = NULL;
    np->value = rand() % 10;
    return np;
}

int main(void)
{
int i;
for(i = 0; i < 10; i++)
{
    list_array[i] = create_node();
}
return 0;
}    
4

6 に答える 6

4

create_nodeポインタを返すので、エラーを修正するために配列をポインタの配列にします。

node_t *list_array[10];

create_nodeにメモリを割り当てていないため、使用npは違法であることに注意してください。試す:

node_t *np = malloc(sizeof *np);

node_t構造体の配列を作成したい

その場合、node_t list_array[10]と:を残すことができます。

  • &list_array[i]関数に引数として渡す
  • 関数に、のnode_t代わりにを返すようにしますnode_t *
于 2013-02-11T10:53:33.597 に答える
4

1つは構造体であり、もう1つは構造体へのポインタであるためです。

この関数はノードへのポインターcreate_node()を返し(ちなみに、この関数では実際に必要です)、配列内の実際の構造にそれを割り当てようとします。malloc()

宣言を次のように変更するだけで解決できます。

node_t *list_array[10];

構造体の配列ではなく、ポインタの配列になるようにします。

于 2013-02-11T10:54:39.743 に答える
4

はポインタcreate_node()返しますが、実際のインスタンスであるためです。インスタンスにポインタを割り当てることはできません。それらは完全に異なります。list_array[i]

解決策は通常、各ノードをポインターとして表すことです。これには、list_arrayポインターの配列が必要です。

node_t *list_array[10];

次に、割り当てが意味をなし、コードがコンパイルされます。

ただし、コードはNULL内部のポインタを逆参照しているため、「機能」しないことに注意してくださいcreate_node()。電話するのを忘れたようですmalloc()

node_t* create_node(void)
{
    node_t *np;
    if((np = malloc(sizeof *np)) != NULL)
    {
        np->next = NULL;
        np->prev = NULL;
        np->value = rand() % 10;
    }
    return np;
}
于 2013-02-11T10:55:00.883 に答える
1

これは、古典的な「ポインタとインスタンス」の混乱です。あなたの警告よりもさらに深刻なことは次のとおりです。

node_t *np;
np->next = NULL;

これはコンパイルされ、次に segfault が実行されます。

この混乱は、ポインターとは何かを誤解しているために発生します。コンパイルすると、ポインターは 140734799803888 のような 1 つの数値になります。この数値は、データの物理的なチャンクを特定するためだけに使用されます。メモリアドレスです。

ポインターとインスタンスは紛らわしく、プログラミングで遭遇する最初の概念上の課題の 1 つです。したがって、ここに類推があります:

GPS を使用したことがある場合、現在地 (ポインター) はわかりますが、現在地(データ)はわかりません。ポインタも同じように機能します。誰かがあなたの手を振ろうとしても、GPS 座標 (ポインター) は振らないでしょう! GPS 座標を使用してあなたの位置を特定し、物理的に訪問して (データ)、握手します。それがポインタの仕組みです。

したがって、上記のコードでは、 pointer を宣言しますnpが、追跡する場所を指定しません。次に、「np私のデータを見つけるために番号を使用してください」と尋ねます(しかし、あなたは番号を設定していませんnp!)特に、np->next場所np + someOffset(未定義です!)を使用して物理データ(どこにもありません)を見つけるように求めます、変更します。

そのため、セグフォルトが発生します。

于 2013-02-11T11:59:05.533 に答える
0

node_t list_array[10]node_t *list_array[10] あなたも、あなたをmalloc編集していないはずですnode_t *np

node_t *np = malloc(sizeof(node_t));

于 2013-02-11T10:54:45.193 に答える
0

このプログラムでは、動的ストレージ期間 (malloc) を使用しても意味がありません。すべてのオブジェクトを静的ストレージ期間に保持したい場合は、memcpy を優先して create_node を破棄します。例えば、

#include <string.h>

typedef struct node
{
    int value;
    struct node *next;
    struct node *prev;
} node_t;

int main(void) {
    node_t list_array[10];
    for (int i = 0; i < sizeof (list_array) / sizeof (*list_array); i++) {
        memcpy(list_array + i,
               &(node_t){ .value = rand() % 10,
                          .next = NULL,
                          .prev = NULL },
               sizeof (*list_array));
    }
    return 0;
}
于 2013-02-11T13:52:21.187 に答える