Jude Jude - 3 months ago 10
C Question

Circular Linked list is crashing while trying to print

So I'm working on a program, that will eventually simulate a lame version of duck duck goose (actually called duck duck boot by the professor). When I read the problem circular linked list is what popped out towards me. Though I am very new at using linked lists in general.

It seems like the program is creating and assigning the nodes, but I crash when I try to print them.

#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;
}
}

Answer

There are 2 problems.

The first is that you're not passing bestFriend to populateList() by address, so it doesn't get changed. populateList() should look like this:

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;
        }
    }
}

And then you call it like this:

populateList(&bestFriend, numberOfFriends);

The second problem is that your condition for the printList() loop is wrong. There is more than one way of writing it, but this do loop works:

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

Reference: Circular Linked List