Linked List not accepting values

Linked List not accepting values

Problem Description:

I need to make a calendar planner with a linked list in C. Im inserting a couple of Elements, and I want to insert them in a sorted order. If I try to print the List, It doesn’t show any output for the description of the appointment.

Code:

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

// Appointment
typedef struct
{
    time_t start;
    char *description;
} Appointment;

// List element
typedef struct Element
{
    Appointment *appointment;
    struct Element *next;
} Element;

// List of appointments
typedef struct
{
    Element *head, *tail;
} List;

void printAppointment(Appointment *appointment)
{
/*
    Print the Appointment structure
*/

    char *description = appointment->description;
    time_t startTime = appointment->start;
    printf("Appointment(%s, %ld)n", description, startTime);
}

Appointment createAppointment(char *description, time_t start)
{
    Appointment appointment = {0};
    appointment.description = description;
    appointment.start = start;

    return appointment;
}

List createList()
/*
    Create a linked list with a head and a tail element
*/
{
    Element *head;
    Element *tail;

    head = malloc(sizeof(Element));
    tail = malloc(sizeof(Element));

    head->next = tail;

    List *list;

    list = malloc(sizeof(List));
    list->head = head;
    list->tail = tail;

    return *list;
}

void clearList(List list)
/*
    Free the list from all memory allocated, but keep the head and the tail
*/
{
    Element *temp;

    // Free elements as long as the head is not pointing to the tail
    while (list.head->next != list.tail)
    {
        // Extract the element after the head into temp, point head at the element after
        temp = list.head->next;
        list.head->next = temp->next;

        // Free the exctracted element
        free(temp);
    }
}

void debugList(List list)
/*
    Print the list to the console
*/
{

    struct Element *current = list.head->next;
    while (current->appointment != NULL)
    {
        printf("%s ", current->appointment->description);
        
        current = current->next;
    }
    printf("n");
}

void insertElement(List list, char *description, time_t start)
/*
    Insert a new element into the list based on its value
*/
{

    printf("Inserting element %s with start time %ldn", description, start);
    Element *new_element = malloc(sizeof(struct Element));
    Appointment new_appointment = createAppointment(description, start);
    
    new_element->appointment = &new_appointment;
    new_element->next = NULL;

    if (list.head->next == list.tail)
    {
        // List is empty, insert new element after the head
        printf("Head is pointing to tail, inserting %s in the middlen", description);
     
        new_element->next = list.tail;
        list.head->next = new_element;
        return;
    }
    else
    {
        // Find the correct position for the new node in the list
        struct Element *current = list.head->next;
        struct Element *prev = list.head;

        int index = 0;

        while (1)
        {
            // If the new value is bigger than the current value, insert it before the current element
            if (current->appointment->start >= start)
            {
                printf("Inserting element %s at position %dn", description, index);
                prev->next = new_element;
                new_element->next = current;
                return;
            }

            // Iterate forwards
            prev = current;
            current = current->next;
            index++;

            // If the new element is bigger than all elements, insert it at the end
            if (current == list.tail)
            {
                prev->next = new_element;
                new_element->next = list.tail;
                return;
            }
        }
    }
}

Element *findElement(List list, char *description)
{
    /*
        Find a element in the list based on its value. Returns nullptr if the element is not found.
    */
    Element *current = list.head->next;
    while (current->next != list.tail)
    {
        Appointment currentAppointment = *current->appointment;
        
        printf("Appointment(%s, %ld)n", currentAppointment.description, currentAppointment.start);
        return NULL;
    }
    printf("Returning NULL, no element found!");
    return NULL;
}

_Bool deleteElement(List list, char *description)
{
    /*
        Find a element in the list based on its value and delete it. Returns true if the element has been deleted.
    */
    Element *current = list.head->next;
    Element *prev = list.head;

    while (current->next != list.tail)
    {
        char *currentDescription = current->appointment->description;

        if (*currentDescription == *description)
        {
            prev->next = current->next;
            free(current);
            return true;
        }
        prev = current;
        current = current->next;
    }

    return false;
}

int main()
{
    // Create the list
    List list = createList();

    // Insert some nodes
    insertElement(list, "test1", time(NULL) - 1000);
    insertElement(list, "test3", time(NULL) - 3000);
    insertElement(list, "test2", time(NULL) - 2000);
    insertElement(list, "test4", time(NULL) - 4000);
    insertElement(list, "test8", time(NULL) - 8000);

    // Print the list
    debugList(list);


    return 0;

    // Search the element with value 3
    Element *el = malloc(sizeof(Element)); 
    el = findElement(list, "test3");

    //printAppointment(el->appointment);
    //printAppointment(el->next->appointment);

    // Delete the element with value 3
    deleteElement(list, "test3");
    debugList(list);

    // clear the list
    clearList(list);

    // print the list again;
    debugList(list);
    return 0;
}

I can’t change any of the structs since those are a given requirement. Im fairly new to C so I dont really know why this is happening and I have absolutely no Idea on how to fix this.

The program has been compiled with gcc -g -Wall -pedantic-errors main.c

Solution – 1

You should pass a pointer to a list when you insert elements. Right now you’re passing a copy, to which you add an element, but this is not applied to your variable but to a copy of your variable. Change your function signature to:

void insertElement(List* list, char *description, time_t start)

and change all code inside the function accordingly to deal with a pointer instead of a value. Your main will look like this:

int main()
{
    // Create the list
    List list = createList();

    // Insert some nodes
    insertElement(&list, "test1", time(NULL) - 1000);
    insertElement(&list, "test3", time(NULL) - 3000);
    insertElement(&list, "test2", time(NULL) - 2000);
    insertElement(&list, "test4", time(NULL) - 4000);
    insertElement(&list, "test8", time(NULL) - 8000);

    // Print the list
    debugList(list);


    return 0;
}

and the insertElement function:

void insertElement(List* list, char *description, time_t start)
/*
    Insert a new element into the list based on its value
*/
{

    printf("Inserting element %s with start time %ldn", description, start);
    Element *new_element = malloc(sizeof(struct Element));
    Appointment new_appointment = createAppointment(description, start);
    
    new_element->appointment = &new_appointment;
    new_element->next = NULL;

    if (list->head->next == list->tail)
    {
        // List is empty, insert new element after the head
        printf("Head is pointing to tail, inserting %s in the middlen", description);
     
        new_element->next = list->tail;
        list->head->next = new_element;
        return;
    }
    else
    {
        // Find the correct position for the new node in the list
        struct Element *current = list->head->next;
        struct Element *prev = list->head;

        int index = 0;

        while (1)
        {
            // If the new value is bigger than the current value, insert it before the current element
            if (current->appointment->start >= start)
            {
                printf("Inserting element %s at position %dn", description, index);
                prev->next = new_element;
                new_element->next = current;
                return;
            }

            // Iterate forwards
            prev = current;
            current = current->next;
            index++;

            // If the new element is bigger than all elements, insert it at the end
            if (current == list->tail)
            {
                prev->next = new_element;
                new_element->next = list->tail;
                return;
            }
        }
    }
}

PS There are more functions in your code where you should pass a pointer to a list instead of a copy.

Not recommended but for completion:

Another solution is to return your list everytime you insert an element, but this will be slower and you have to reassign your list everytime you insert a new element, so NOT recommended but here is the function signature anyway:

List insertElement(List list, char *description, time_t start)
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject