Setting a condition to avoid double freeing allocated memory

cfreemalloc

Ubuntu 10.10 gcc 4.4.4

I am just experimenting with allocating and freeing.

However, I am trying to avoid the problem when a object is freed more than once.

However, when I test I notice that the obj that is created and freed doesn't return to a null state. So is there any condition that I can set that will avoid if this did happen?

I also tried setting the object to NULL after the free. However, it still tried to free the object.

This is a reference to this question, just so you know is not a duplicate:
freeing allocated memory

My code below:

#include <stdio.h>
#include "objects.h"

int main(void)
{
    obj_t *obj = NULL;

    obj = create_object();

    destroy_object(obj);

    destroy_object(obj);

    return 0;
}

==

#ifndef OBJECTS_H_INCLUDED
#define OBJECTS_H_INCLUDED

typedef struct Obj_t obj_t;

obj_t* create_object();
void destroy_object(obj_t *obj);

#endif /* OBJECTS_H_INCLUDED */

==

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

#include "objects.h"

struct Obj_t {
    int obj_id;
};

obj_t* create_object()
{
    obj_t *obj = malloc(sizeof obj);

    return obj;
}

void destroy_object(obj_t *obj)
{
    if(obj != NULL) {
        printf("Object [ %d ] will be deleted\n", obj->obj_id);
        free(obj);
    }
}

==

OBJECT_FILES = objects.o main.o
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0
CC = gcc
TARGET = obj

$(TARGET): $(OBJECT_FILES)
    $(CC) $(CFLAGS) $(OBJECT_FILES) -o $(TARGET)

main.o: main.c objects.c
    $(CC) $(CFLAGS) -c main.c

objects.o: objects.c
    $(CC) $(CFLAGS) -c objects.c 

clean:
    rm -f $(OBJECT_FILES) $(TARGET) *~

Best Answer

The problem is that the value of the pointer in Main is never updated, because you're passing a copy of the pointer to destroy_object. What you need is a pointer to the pointer. Try this:

void destroy_object(obj_t **obj)
{
    if(*obj != NULL) {
        printf("Object [ %d ] will be deleted\n", *obj->obj_id);
        free(*obj);
        *obj = NULL;
    }
}

Then:

destroy_object(&obj);
Related Topic