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

Time:04-03

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?

CodePudding user response:

If you want to modify the pointer's value, then you need to pass a pointer to the pointer:

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

int main() {
    char data[] = "foo";
    object_t *obj = object_new(data);
    object_delete(&obj);
}

Note that there's not much point in null-testing the pointer, because free does that anyway.

CodePudding user response:

Pointers are values, and C is a pass-by-value language.

In other words, object_t *obj is a local copy of the pointer passed to object_delete.

One option is another level of indirection.

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

int main(void) {
    object_t *foo = object_new("42");
    object_delete(&foo);
}

CodePudding user response:

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;
}
  • Related