Search code examples
cpointersdynamic-memory-allocationfree

Free dynamically allocate struct in C by typecasting


I have a struct that is defined as

typedef struct
{
    int id;
    char* name;
    float percentage;
}student_t;

And in a given function

void student_tDeleter(void* val_ref) {
    
}

I understand that if a function had to take in void* ptr as its parameter, I have to do type cast in order to access to its memeber variables, but the following code won't work for some reason

void student_tDeleter(void* val_ref) {
    free((student_t*)val_ref->id);
    free((student_t*)val_ref->name);
    free((student_t*)val_ref->percentage);
    free(val_ref)
    val_ref = NULL;
}

Compiler says that ```warning: dereferencing void* pointer error: request for memeber "id/name/percentage" in something not a struct or union

I thought its the parentheses. So I added two extra parentheses

void student_tDeleter(void* val_ref) {
    free(((student_t*)val_ref)->id);
    free(((student_t*)val_ref)->name);
    free(((student_t*)val_ref)->percentage);
    val_ref = NULL;
}

But compiler says that

  free(((student_t*)val_ref)->id);
error: incompatible type for argument 1 of ‘free’
  free(((student_t*)val_ref)->percentage);
 note: expected ‘void *’ but argument is of type ‘float’
 extern void free (void *__ptr) __THROW;

How do I properly free() struct memebers? Any reply is appreciated.


Solution

  • Operator precedence

    -> beats cast.

    (student_t*)val_ref->id
    // is like
    (student_t*)(val_ref->id)
    

    Instead use

    ((student_t*)val_ref)->id
    

    Free pointers

    @Vlad from Moscow nicely points out code should not attempt to "free" a float nor int.


    Repaired code

    As free(NULL) is OK, let us also allow student_tDeleter(NULL).

    void student_tDeleter(void* val_ref) {
      if (val_ref) {
        free(((student_t*)val_ref)->name);
        free(val_ref)
      }
    }