0

リンクリストを含む簡単なプログラムを作成しました。作成された関数にリンクリストを表示しようとすると、正常に機能します。ただし、メインに戻って表示しようとすると、正しく動作しません。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

#define LEN 20 
struct Node {
char word[LEN];
int count;
Node * next;
};

Node* build_linked_list (char array[][LEN], int N);
Node* make_ordered_copy (Node * head);
void print_list(Node * head);


int main()
{
#define NUMBER 10
char array[NUMBER][LEN]; // array which the words will be recorded
int N=6;
for(int a=0; a<N; ++a) strcpy(array[a], "test");
print_list(build_linked_list(array, N));
getchar();
return 0;
}

Node* build_linked_list (char array[][LEN], int N)
{
  Node ndArray[N];
  Node *head, *newnode;

  head = &ndArray[0];
  strcpy(head->word, array[0]); // writing the first element to the head
  head->count = 0;
  head->next = NULL;

  for(int a=1; a<N; ++a) // writing the elements in a linked list 
  {
    newnode = &ndArray[a];
    strcpy(newnode->word, array[a]); 
    newnode->count = 0;
    newnode->next = head; // first location now becomes second location
    head = newnode;
  }  

  print_list(head);
  printf("Previous values were shown in build_linked_list\n");

  return head;
}

void print_list(Node* head)
{
 Node* traverse;
 traverse = head;

 while(traverse) // while traverse is not NULL
 {
   printf("\"%s\" with the frequency of %d\n", traverse->word, traverse->count);
   traverse = traverse->next;
 }


 return;
}

mainから呼び出されたprint_list関数でデバッグする場合、「traverse-> word」は最初は正しい値を表示しますが、正しく出力されず、その後別の値に変更されます。

4

2 に答える 2

0

の要素はndArray、のスコープ内でのみ有効ですbuild_linked_list。プログラムがその関数に存在すると、それらの要素にアクセスすると未定義の動作が発生します。これらの要素を使用してリンクリストを作成しています。代わりに、ヒープ上のリンクリストのノードにメモリを割り当てるか、ndArray変数をファイルスコープに移動して、mainメソッドの存続期間中存在するようにする必要があります。

于 2013-03-24T21:17:06.757 に答える
0

あなたの中build_linked_listには宣言しています

Node ndArray[N];

これは、その関数内で入力しているノードです。しかし、実行が終了すると、build_linked_list関数のブロックのndArray割り当てが解除されるため、返されたポインタは、以前に割り当てられたメモリを指しますndArrayが、現在はその配列によって占有されていません。

リンクリストの通常の実装は、ヒープと動的メモリ割り当てを使用して行われます。ノード配列を構築するときは、次のように書く必要があります。

Node* ndArray = new ndArray[N];

しかし、この時点で、ガベージコレクターと動的メモリを適切に管理する方法について読むことを強くお勧めします。これは、StackOverflowで何度も議論されてきたまったく新しいトピックだからです。

この回答については、newまたはを割り当てるときにnew[]( Cリファレンスmallocfree参照してください)、deleteまたはをdelete[]それぞれ削除する必要があることを予期します。この場合、リンクリストを使い終わったとき、または次のndArrayように書く必要があります。

delete[] ndArray;

メモリを解放します。そうしないと、メモリリークが発生します。

于 2013-03-24T21:29:37.173 に答える