简体   繁体   中英

Linked List in C - Segmentation Fault

I am a beginner, learning how to make linked lists in C. Whenever I try to print out the list, the list prints out just fine but I always end up with a segmentation fault at the end.

When I use GDB backtrace, it points me to the line -> entry = *((*node).data); in the printContents function.

However I am not quite sure what's wrong with it.

Here is the linked list code:

void createEmptyLinkedList(LinkedList *inList) {
    inList = (LinkedList*)malloc(sizeof(LinkedList));

    (*inList).head = NULL;
    (*inList).tail = NULL;

    (*inList).size = 0; //Keeps track of size of list

    return;
} 
void insertAtStart(LinkedList *inList, JournalEntry *inValue) {
    LinkedListNode *newNode;
    int listSize = (*inList).size;

    newNode = (LinkedListNode*)malloc(sizeof(LinkedListNode));

    (*newNode).data = inValue;
    (*newNode).next = (*inList).head;
    (*inList).head = newNode;
    ((*inList).size)++;
    return;
}

void printContents(LinkedList *inList) {
    LinkedListNode *node;
    JournalEntry entry;

    node = (*inList).head;

    while (node != NULL) {

            entry = *((*node).data);

            printf("%04d-%02d-%02d: %s\n", entry.year, entry.month, entry.day, entry.text);

            /*Move node to the next node*/
            node = (*node).next;
    }
    printf("Done!");
    return;
}
//Free nodes recursively
void freeLinkedList(LinkedList *inList) {
    freeNode((*inList).head);
    free(inList);
    return;
}

void freeNode(LinkedListNode *node) {
    if (node != NULL) {
    freeNode((*node).next);
    free(node);
}

Here is the main function used to start the linked list:

int main() {
    LinkedList list;
    JournalEntry *value;
    char* textToEnter;

    value = (JournalEntry*)malloc(sizeof(JournalEntry));

    createEmptyLinkedList(&list);

    textToEnter = "Hello";
    (*value).day = 10;
    (*value).month = 5;
    (*value).year = 2010;
    strcpy((*value).text, textToEnter);
    insertAtStart(&list, value);

    printContents(&list);

    freeLinkedList(&list);
    return 0;
}

And just in case anyone needs it, here are the structs declared in the header file:

typedef struct LinkedListNode {
    JournalEntry *data;
    struct LinkedListNode *next;
} LinkedListNode;
typedef struct {
    LinkedListNode *head;
    LinkedListNode *tail;
    int size;
} LinkedList;
typedef struct {
    int day;
    int month;
    int year;
    char text[1000];
} JournalEntry;

Everything in C is passed by value, including pointers. So, assigning to inList won't affect the value the caller has passed. Rather, you should be taking a pointer to a pointer if you want to do it this way:

void createEmptyLinkedList(LinkedList **inList) {
    *inList = malloc(sizeof(LinkedList));

    (*inList)->head = NULL;
    (*inList)->tail = NULL;

    (*inList)->size = 0; //Keeps track of size of list

    return;
}

Without this, you're just working with an uninitialized pointer to hold your list. In your main code you also need to change it like:

LinkedList *list;
createEmptyLinkedList(&list);

Notice that list is declared as a pointer here.

The way I see it, problem is you didn't decide whether createEmptyLinkedList() should allocate memory for your head, or you will do it in main() function.
And you did both.
In main()
you did LinkedList list; -- this part creates LinkedList structure.
Then you pass address of that structure to your function. And that's fine to this point.

In your createEmptyLinkedList() you have inList pointer pointing to list structure. And that's fine as well.

But now you mess things up and malloc() another LinkedList structure, making inList point to newly malloc'd structure.

Then you initialize you brand new LinkedList structure, return from createEmptyLinkedList() without changing list structure in main() because you initialized your newly malloc'd structure, not list .

You can fix it by deciding whether your LinkedList structure will be created in main() or createEmptyLinkedList() .
If you choose 2nd -- read above answer.
But if you choose 1st -- leave everything as it is and remove line in createEmptyLinkedList() that is responsible for malloc'ing.

Then, as FatalError suggested - more appriopriate name to your function would be initializeEmptyLinkedList because there is no create part anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM