Search code examples
cnullheap-memorypersistence

Setting a Pointer to `NULL` Inside a Function and Having it Stay `NULL` in C


I'm fairly new to the C programming language, and I am trying to make an idiomatic pattern for creating structures (i.e. a series of standard constructors, destructors, etc.) like so:

typedef struct _OBJECT
{
    char *data;
} object_t;

object_t *object_new(char *data)
{
    object_t *ret = malloc(sizeof(*ret));

    if (ret != NULL)
        ret->data = data;

    return ret;
}

void object_delete(object_t *obj)
{
    if (obj != NULL)
    {
        free(obj);

        obj = NULL;
    }
}

I seem to be having an issue with making a destructor-esque function, though, as I am unable to set the argument of the function to NULL after freeing it. I am fairly sure this has to do with the fact that data declared on the stack in a callable object is impersistent. Is there a way to make this declaration persistent or is setting the pointer to NULL outside the function the best way of handling things?


Solution

  • I am unable to set the argument of the function to NULL after freeing it...

    If you want to set the argument to NULL, change the parameter type of function to double pointer and pass the address of object to the function. Dereferencing the function parameter will give you the object, whose address passed as argument, which then you can set to NULL after deallocating memory. That said, below are the changes you need to do in object_delete() function:

    void object_delete(object_t **obj)  // change parameter type to double pointer
    {
        if (*obj != NULL)      // dereferencing parameter will give object
        {
            free(*obj);        // free object
    
            *obj = NULL;       // set object to NULL
        }
    }
    

    Call object_delete() function like this:

    int main() {
        object_t * x = object_new ("str");
    
        object_delete (&x);  // pass address of pointer x
    
        // check x
        printf ("x is %sNULL\n", x == NULL ? "" : "not ");
    
        return 0;
    }