Search code examples
cmallocfree

free function seems to not work


I have this problem in C, happened about 3 times and I just cant find the answer. I'm allocating a memory in a create function, and when I'm trying to free it in a destroy the program crashes.

Here is the program:

typedef struct Order_t* Order;
struct Order_t {
    char* email;
    TechnionFaculty faculty;
    int id;
    char* time;
    int num_ppl;
};

Order createOrder(char* email, TechnionFaculty faculty, int id, char* time,
    int num_ppl)
{
    if (email == NULL) {
        return NULL;
    }
    if (checkEmail(email) != OK)
        return NULL;
    if (checkFaculty(faculty) != OK)
        return NULL;
    Order order = malloc(sizeof(Order));
    if (order == NULL)
        return NULL;
    (order->email) = malloc(strlen(email) + 1);
    if (order->email == NULL) {
        free(order);
        return NULL;
    }
    strcpy(order->email, email);
    order->faculty = faculty;
    order->id = id;
    order->num_ppl = num_ppl;
    order->time = malloc(strlen(time) + 1);
    if (order->time == NULL) {
        free(order->email);
        free(order);
        return NULL;
    }
    return order;
}

void orderDestroy(Order order)
{
    assert(order != NULL);
    free(order->email);
    free(order->time);
    free(order);
}

Solution

  • I did some small changes to your code so that it doesn't crash. When using a struct you should allocate both the struct and its members. I hope it can help you.

    #include <stdio.h>
    #include <memory.h>
    #include <stdlib.h>
    #include <assert.h>
    
    typedef struct Order_t *Order;
    struct Order_t{
        char* email;
        //TechnionFaculty faculty;
        int id;
        char* time;
        int num_ppl;
    };
    
    Order createOrder (char* email, int id, char* time, int num_ppl){
        if (email == NULL) {
            return NULL;
        }
    
        Order order = malloc(sizeof(struct Order_t));
        if (order == NULL)
            return NULL;
        (order->email) = malloc(strlen(email)+1);
        if (order->email == NULL){
            free(order);
            return NULL;
        }
        strcpy(order->email, email);
        order->id = id;
        order->num_ppl = num_ppl;
        (order->time) = malloc(strlen(time)+1);
        if (order->time == NULL){
            free(order->email);
            free(order);
            return NULL;
        }
        return order;
    }
    
    void orderDestroy (Order order){
        assert(order != NULL);
        free(order->email);
        free(order->time);
        free(order);
    }
    
    int main() {
        printf("Hello, World!\n");
        Order o1 = createOrder("foo", 42, "24", 420);
        orderDestroy(o1);
        return 0;
    }
    

    We check it with .

    $ ./a.out 
    Hello, World!
    developer@1604:~/CLionProjects/untitled4$ valgrind ./a.out 
    ==16288== Memcheck, a memory error detector
    ==16288== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==16288== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
    ==16288== Command: ./a.out
    ==16288== 
    Hello, World!
    ==16288== 
    ==16288== HEAP SUMMARY:
    ==16288==     in use at exit: 0 bytes in 0 blocks
    ==16288==   total heap usage: 4 allocs, 4 frees, 1,063 bytes allocated
    ==16288== 
    ==16288== All heap blocks were freed -- no leaks are possible
    ==16288== 
    ==16288== For counts of detected and suppressed errors, rerun with: -v
    ==16288== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)