2016-03-21 10 views
0

私はプログラムに取り組んでいます。その結果、最終的にはアヒルのガチガチの模様がシミュレートされます。私が問題を読んだとき、循環リンクされたリストは私に向かって飛び出しました。私は一般的にリンクされたリストを使用することで非常に新しいですが。印刷しようとしている間に循環リンクされたリストがクラッシュする

プログラムがノードを作成して割り当てているようですが、それらを印刷しようとするとクラッシュします。

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

typedef struct { 
    char name[20]; 
    struct jimmysFriend *next; 
} jimmysFriend; 

jimmysFriend *createNode(); 
void populateList(jimmysFriend *bestFriend, int numberOfFriends); 
//void duckDuckBoot(); 
void printList(jimmysFriend *bestFriend); 

int main(void) { 
    int i; 
    int cases; 
    int numberOfFriends; 
    scanf("%d", &cases); 
    for (i = 0; i < cases; i++) { 
     scanf("%d", &numberOfFriends); 
     jimmysFriend *bestFriend; //head 
     bestFriend = NULL; 
     populateList(bestFriend, numberOfFriends); 
     printList(bestFriend); 
    } 
    return 0; 
} 

void populateList(jimmysFriend *bestFriend, int numberOfFriends) { 
    int i; //Where I actually create the circular list. 
    jimmysFriend *aFriend; 
    for (i = 0; i < numberOfFriends; i++) { 
     aFriend = createNode(); 
     if (bestFriend == NULL) { 
      bestFriend = aFriend; 
      aFriend->next = aFriend; 
     } else 
     if (bestFriend != NULL) { 
      jimmysFriend *temptr; 
      aFriend->next = bestFriend; 
      temptr = bestFriend; 
      while (temptr->next != bestFriend) { 
       temptr = temptr->next; 
      } 
      temptr->next = aFriend; 
     } 
    } 
} 

jimmysFriend *createNode() { //Creates a node 
    jimmysFriend *aFriend; 
    aFriend = malloc(sizeof(jimmysFriend)); 
    if (aFriend != NULL) { 
     scanf("%s", aFriend->name); 
    } 
    return aFriend; 
} 

void printList(jimmysFriend *bestFriend) { //Problem area? 
    jimmysFriend *temptr; 
    temptr = bestFriend; 
    while (temptr->next != bestFriend) { 
     printf("%s\n", temptr->name); 
     temptr = temptr->next; 
    } 
} 
+0

明白な問題の1つは、リンクされたリストに1つのアイテムしか含まれていない場合です。その場合、 'populateList'は' bestFriend = aFriend; 'と' aFriend-> next = aFriend; 'を設定します。つまり、 'printList'の' while'ループは何も印刷せずに終了します。一般的には、whileループは、リストより少ないエントリを1つ印刷します。 – user3386109

+0

@ user3386109あなたの言うことが意味を見るのは、リストに 'printList'の1つの項目しか含まれていないかどうかをチェックするif文を持っていることです。 – Jude

+0

1) 'typedef struct' - >' typedef struct jimmysFriends' 2) 'aFriend = malloc(sizeof(jimmysFriend));' - > 'aFriend =(jimmysFriend *)malloc(sizeof(jimmysFriend)); ' – DimChtz

答えて

2

2つの問題があります。

最初に、アドレスでpopulateList()bestFriendを渡していないので、変更されません。 populateList()は次のようになります。

void populateList(jimmysFriend **bestFriend, int numberOfFriends){ 
    int i; //Where I actually create the circular list. 
    jimmysFriend* aFriend; 
    for(i = 0; i < numberOfFriends; i++){ 
     aFriend = createNode(); 
     if(*bestFriend == NULL){ 
      *bestFriend = aFriend; 
      aFriend->next = aFriend; 
     } 
     else if(*bestFriend != NULL){ 
      jimmysFriend* temptr; 
      aFriend->next = *bestFriend; 
      temptr = *bestFriend; 
      while(temptr->next != *bestFriend){ 
       temptr = temptr-> next; 
      } 
      temptr->next = aFriend; 
     } 
    } 
} 

そして、あなたはこのようにそれを呼び出す:

populateList(&bestFriend, numberOfFriends); 

第二の問題は、printList()ループのためのあなたの状態が間違っているということです。そこにそれを書くのに複数の方法があるが、これdoループが動作します。

void printList(jimmysFriend* bestFriend){ //Problem area? 
    if (bestFriend != NULL) { 
     jimmysFriend* temptr = bestFriend; 
     do { 
      printf("%s\n", temptr->name); 
      temptr = temptr->next; 
     } while (temptr != bestFriend); 
    } 
} 

参考:populateListでCircular Linked List

+0

私はいつも参照によって関数に渡すだけで元の変数を変更できると思っていました。だから私の元の変数は、それがダブルポインタにする必要がある関数から行われた変更を維持することができるようにするポインタですか? また、私のループ条件が間違っていますか?実際に何が本当に間違っていたのか分かりません。しかし、あなたの提案はうまくいく!ありがとう! – Jude

+0

Judeはループが機能しない理由について@ user3386109のコメントを参照してください。 –

1

()ジミーさんの親友は本当にときに、リストの先頭に指摘されていませんその機能で実行されます。 populateList()で行った代入は失われます。

jimmyの親友を関数へのポインタのアドレスとして渡します。だからpopulateList()はjimmysFriend ** bestFriendを受け入れます。次に、そこにヘッドを格納しようとすると、あなたが頭にしたいノードを* bestFriendに割り当てます。

printList()を呼び出す直前に、Jimmyの親友がNULLかどうかを確認することで、いつでもそれを検証できます。

関連する問題