Vans S
Vans S

Reputation: 1813

how to correctly free a struct? ANSI C

How does one correctly free a structure? If I have is this right? Or just called free once is correct?

typedef struct AStruct{
    char * buffer;
    int size;
} AStruct;

typedef struct S_Session {
    int Id;
    AStruct* buff;
    char * name;
} S_Session;

S_Session* S_Session_new() {
    S_Session* s = (S_Session*)malloc(sizeof(S_Session));
    s->Id = 1;
    s->buff = (AStruct*)malloc(sizeof(AStruct));
    s->buff->buffer = malloc(8196);
    s->buff->size = 8196;
    s->name = malloc(100);
    return s;
}

int main(int argc, char *argv[]) 
{
   S_Session* sess = S_Session_new();
   free(sess->buff->buffer);
   free(sess->buff);
   free(sess->name);
   free(sess);
}

Upvotes: 1

Views: 542

Answers (2)

jxh
jxh

Reputation: 70442

In C, you should not cast the return value of malloc(). It can mask an error in the case that the prototype is missing, and the worst case result of using that value may be a crash.

In general, you should check the validity of a function call result before acting upon it. In this case, checking to see if malloc() actually succeeds will avoid a likely unintended crash in the case the system ran out of memory.

Since you can calculate exactly how much memory you need, you can implement your S_Session_new() to perform a single allocation of all the memory you need, and set the pointers to the right places within that memory. Doing so allows you to release that memory with a single call to free().

S_Session* S_Session_new() {
    char *mem;
    S_Session* s = 0;
    size_t sz = 0;

    sz += sizeof(S_Session);
    sz += sizeof(AStruct);
    sz += 8196;
    sz += 100;

    mem = malloc(sz);
    if (mem) {
        s = (void *)mem;
        s->Id = 1;
        s->buff = (void *)(mem += sizeof(S_Session));
        s->buff->buffer = (void *)(mem += sizeof(AStruct));
        s->buff->size = 8196;
        s->name = (void *)(mem += 8196);
    }
    return s;
}

Upvotes: 0

João Pinho
João Pinho

Reputation: 3775

The rule like others have already said is to free everything you allocate, so from your code, you have 4 malloc's and you call free for those mallocs when the programs ends, which is correct.

In C nothing is automatic, so if you decided to call free only over your allocated struct, the remaining memory that you allocated would not been freed.

But for just a simple program, after the program ends the process is killed and the memory is freed by the Operating System, so it would be the end of the world if your release just the struct.

As a good practice you should free all the allocate memory by your program before it's termination.

Upvotes: 2

Related Questions