1

学習のために、簡単な連結リストの実装を書いています。リンクされたリストは、値と次のノードへのポインターをnode含む構造で構成されています。intコードを実行すると、NULL ポインターに達したときに終了する必要があるにもかかわらず、無限にループします。私は何を間違っていますか?

#include <stdio.h>

struct node {
  int value;
  struct node *next_node;
};

struct node * add_node(struct node *parent, int value)
{
  struct node child;
  child.value = value;
  child.next_node = NULL;

  parent->next_node = &child;
  return parent->next_node;
}

void print_all(struct node *root)
{
  struct node *current = root;

  while (current != NULL) {
    printf("%d\n", current->value);
    sleep(1);
    current = current->next_node;
  }
}


int main()
{
  struct node root;
  root.value = 3;

  struct node *one;
  one = add_node(&root, 5);
  print_all(&root);
}
4

2 に答える 2

5

あなたのプログラムは未定義の動作を示します: ローカルに割り当てられstructたここへのポインタを設定しています:

struct node child;
child.value = value;
child.next_node = NULL;

parent->next_node = &child;
return parent->next_node;

はスタック上にあるためchild、それを指す親を返すと、未定義の動作が発生します。

child機能させるには、動的に割り当てる必要があります。

struct node *pchild = malloc(sizeof(struct node));
// In production code you check malloc result here...
pchild->value = value;
pchild->next_node = NULL;

parent->next_node = pchild;
return parent->next_node;

freeメモリを動的に割り当てたので、メモリ リークを防ぐために、リンク リストの動的に割り当てられた各ノードを呼び出すことを忘れないでください。

于 2013-08-17T18:04:38.097 に答える
4

add_nodeすぐにスコープ外になり、他の関数で再利用される可能性があるローカル変数へのポインターを返します。これにアクセスしようとするとprint_all、未定義の動作が発生します。あなたの場合、アドレスはcurrentポインターによって再利用され、 をroot->next_node指しているように見えますroot

これを修正するには、新しいノードにメモリを割り当てる必要がありますadd_node

struct node * add_node(struct node *parent, int value)
{
    struct node* child = malloc(sizeof(*child));
    if (child == NULL) {
        return NULL;
    }
    child->value = value;
    child->next_node = NULL;

    parent->next_node = child;
    return child;
}

これはメモリを動的に割り当てるため、後で呼び出す必要がありますfree。toorootを使用して割り当てられるように変更しない限り、解放しようとしないでください。malloc

于 2013-08-17T18:04:37.550 に答える