Thread: Using of malloc of Structs - C

  1. #1
    Registered User
    Join Date
    Nov 2019
    Posts
    70

    Using of malloc of Structs - C

    Suppose we have the following code representing a structure of calendar and dates:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    // part 1:
    typedef struct Date Date;
    
    
    struct Date {
        unsigned int day; // a number between 1 to 31
        unsigned int month; // a number between 1 to 12
        char * event;
        Date * next_date;
    };
    
    
    Date * create_date(unsigned int day,
                       unsigned int month, char * event)
    {
        if (!(day >= 1 && day <= 31) ||
            !(month >= 1 && month <= 12) ||
            event == NULL) {
            return NULL;
        }
        Date * d = (Date *) malloc (sizeof(Date));
        if (d == NULL) {
            return NULL;
        }
        d->day = day;
        d->month = month;
        d->event = event;
        d->next_date = NULL;
        return d;
    }
    
    
    int are_equals(Date * date1, Date * date2)
    {
        if (date1 == NULL || date2 == NULL) {
            return 0;
        }
        if (date1->day == date2->day && date1->month == date2->month) {
            return 1;
        }
        return 0;
    }
    
    
    void free_date(Date *date)
    {
        if (date != NULL) {
            free(date);
        }
    }
    
    
    // part 2:
    typedef struct Calendar {
        Date * first_date;
    } Calendar;
    
    
    void init_calendar(Calendar * c)
    {
        c->first_date = NULL;
        return;
    }
    
    
    
    
    int add_to_calendar(Calendar * c, unsigned int day,
                        unsigned int month, char * event)
    {
        if (c == NULL) {
            return 0;
        }
        Date* f = c->first_date;
        if (f == NULL) {
            c->first_date = create_date(day, month, event);
            if (c->first_date == NULL) {
                return 0;
            }
            return 1;
        }
        else {
            if (f->day == day && f->month == month) {
                return 0;
            }
            Date* prevDate = f;
            Date* nextDate = f->next_date;
            while (nextDate != NULL) {
                if (nextDate->day == day && nextDate->month == month) {
                    return 0;
                }
                prevDate = nextDate;
                nextDate = nextDate->next_date;
            }
            prevDate->next_date = create_date(day, month, event);
            if (prevDate->next_date == NULL) {
                return 0;
            }
    
    
            return 1;
        }
    }
    
    
    void free_calendar(Calendar * c)
    {
        if (c == NULL) {
            return;
        }
        Date* date = c->first_date;
        if (date == NULL) {
            return;
        }
    
    
        Date* nextD = NULL;
        while (date != NULL) {
            nextD = date->next_date;
            free(date);
            date = nextD;
        }
        c->first_date = NULL;
    }
    
    
    void print_calendar(Calendar * c)
    {
        if (c == NULL) {
            return;
        }
        Date * current = c->first_date;
        while (current != NULL) {
            printf("%s\n", current->event);
            current = current->next_date;
        }
    }
    
    int main()
    {
    
    
        Calendar c;
        init_calendar(&c);
        add_to_calendar(&c, 19, 8, "Exam_C");
        add_to_calendar(&c, 20, 9, "Exam_CPP");
        print_calendar(&c);
        free_calendar(&c);
        return 0;
    }
    But, in add_to_calendar function I want to change some of the code slightly, such that, instead of this implementation:
    Code:
            prevDate->next_date = create_date(day, month, event);
            if (prevDate->next_date == NULL) {
                return 0;
            }
    
    
            return 1;
    I want to implement the exact thing but a little differently (omit the validation of the "legal" range of day and month for simplicity):
    Code:
            prevDate->next_date = (Date*)malloc(sizeof(Date));
            if (prevDate->next_date == NULL) {
                return 0;
            }
            prevDate->next_date->day = day;
            prevDate->next_date->month = month;
            prevDate->next_date->event = event;
    
    
            return 1;
    But, this implementation causes errors of Uninitialised values in Valgrind - and I don't understand why.

    To my understanding, my implementation does the exact thing (except for the range validation for simplicity) as the first one.
    I'm catching the last date in the calendar, taking its next_date field, allocating to it a pointer to Date struct and assigning this struct fields' as needed.

    What's the problem?

    Thanks in advance!

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    694
    It looks like you are missing this:
    Code:
    prevDate->next_date->next_date = NULL;
    BTW, don't do this:
    Code:
            if (prevDate->next_date == NULL) {
                return 0;
            }
            return 1;
    Instead, do this
    Code:
            return prevDate->next_date != NULL;


    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  3. #3
    Registered User
    Join Date
    Nov 2019
    Posts
    70
    Super!
    Thank you so much John!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with structs and malloc
    By sahtopi in forum C Programming
    Replies: 14
    Last Post: 02-03-2016, 07:29 AM
  2. Malloc, Pointers, and Structs
    By TheSquid in forum C Programming
    Replies: 8
    Last Post: 09-15-2009, 11:07 AM
  3. help with structs and malloc!
    By coni in forum C Programming
    Replies: 20
    Last Post: 09-14-2009, 05:38 PM
  4. Malloc/and structs plz help
    By dezz101 in forum C Programming
    Replies: 1
    Last Post: 09-11-2008, 07:44 PM
  5. Malloc with structs.
    By jrdoran in forum C Programming
    Replies: 4
    Last Post: 12-11-2006, 11:26 PM

Tags for this Thread