0
typedef struct vertex{
    int num;
    struct vertex *next;
} Vertex;

Vertex *adj[1];

void buildList(){
    Vertex *v=NULL;
    Vertex *t=NULL;

    v = malloc(1*sizeof(*v));
    v->num = 1;
    adj[0] = v;  //a NODE with value 1
    t = v;

    v = malloc(1*sizeof(*v));
    v->num = 1;
    t->next = v; // and ANOTHER NODE but it should be the SAME NODE with the above one
    t = v;


    //v = malloc(1*sizeof(*v));
    //v->num = 1;
    //t->next = adj[0]; // causes infinite loop...
    //t = v;
}

予想される出力は、値 1 を持つノードであり、隣接リストにそれ自体があり、1 -> 1 のような出力です。

ここで私の問題は、2 つの異なるノードがあるように見えることです。それらの1つを変更しても、もう1つは変更されず、別のノードのように機能します。

たとえば、リストを作成した後、ノードの値を変更すると、3 -> 3 のような出力が得られます。しかし、3 -> 1 になります。ノードの変更は、他のノードには影響しません。adj[0] を t->next に向けようとすると、無限ループが発生します...

4

5 に答える 5

2

あなたが何を望んでいるのか、私には完全には明らかではありません。Vertexそれ自体を指す場合は、単純に

void buildList(){
    adj[0] = malloc(1*sizeof(*adj[0])); // allocate memory for one Vertex
    if (adj[0] == NULL){
        perror("Allocation of Vertex failed\n");
        exit(EXIT_FAILURE);
    }
    // adj[0] contains the adress of a Vertex
    // set the num of the Vertex
    adj[0]->num = 1;
    // set the next pointer of the Vertex to its address
    adj[0]->next = adj[0];
}

これがあなたが望んでいるものではないことをどのように明確にすることができますか?

于 2011-12-14T14:57:03.510 に答える
1

望むだけの結果が得られることは十分に期待できますが、それが実現するわけではありません。

明らかに 2 つのノードを作成しており、混乱を招くように再利用vしています。

あなたが何をしようとしているのかは完全にはわかりません。しかし、コードをクリーンアップして 2 行の読み取りを削除すると、t = v;おそらく何が起こっているのかが明らかになります。

v->next自分自身を指したい場合は、それを行う必要があります。1 つのノードが必要な場合は、malloc()1 回だけ呼び出されるようにコードを構成する必要があります。

Vertex *v;は頂点を宣言しないことに注意してください。頂点へのポインターを宣言します。

于 2011-12-14T12:55:14.637 に答える
1

関数とリストの使用方法を確認するには、コード全体を提供する必要があります。実際のエラーはおそらく別の場所にあります。リストの最後に到達した場合、どのように比較しますか?

通常、nextリンク リストの最後のノードのポインタが割り当てられNULLます。これにより、無限ループが発生する可能性が低くなります。


通常、次のようにします。

void buildList(){
  // the list base
  adj[0] = malloc(1*sizeof(*v));
  adj[0]->num = 1;
  adj[0]->next = adj[0]; // <-- make the last node point to itself

  // append more items to the end of the list
  Vertex *v=adj[0];
  while (v != v->next) v = v->next; // <-- find the end of the list
  int i;
  int num_nodes = 1; // <-- specify the number of nodes you want in total
  for (i = 1; i < num_nodes; i++) {
    // append another item
    v->next = malloc(1*sizeof(*v)); 
    // initialize it
    v = v->next;
    v->num = i; 
    v->next = v; // <-- make the last node point to itself
  }
}

あなたが説明する無限ループは、おそらくリストベースをリストの最後に割り当てたという事実から来ています。したがって、効果的にリストをサイクルにします。

于 2011-12-14T12:55:16.757 に答える
1

コード スニペットは次のように分析できます。

    ポインター v を malloc して割り当てています。次の要素を指すポインタ v->next は初期化されていないことに注意してください。
    次に、v を adj[0] と t にコピーします。そして、vの再初期化が再び発生し(これは冗長だと思います)、その値を設定し、その値をt-> nextにコピーします
    これまでのところ、 t がそれ自体を指すようになりました。つまり、 1 が 1 を指すようになりました。 iyself を指す変数は使用できなくなりました
    コードのコメント部分では、adj[0] is v と同じことが発生します。したがって、無限ループに関しては、作業で上記のスニペットを使用したことが原因であり、個別に実行すると、アクセス時にセグメンテーション エラーが発生します。 t->次へ
于 2011-12-14T14:42:57.890 に答える
0

作成されたコードは、2 つの別個のノードを作成し、後でノード t=v を再割り当てするだけのように見えます。これにより、ポインターは 1 つのノードのみを指すようになります。

アレイ上のノード 1 のバックアップとその背後にある理由は明確ではありません。

達成しようとしているロジックを説明できれば幸いです。

于 2011-12-14T13:14:49.790 に答える