在函数内部设置指向“NULL”的指针并在 C 语言中保持“NULL”

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

我是 C 编程语言的新手,我正在尝试创建一个惯用的模式来创建结构(即一系列标准构造函数、析构函数等),如下所示:

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

不过,我似乎在制作类似析构函数的函数时遇到了问题,因为我无法在释放函数后将函数的参数设置为 NULL。我相当确定这与在可调用对象的堆栈上声明的数据是不持久的这一事实有关。有没有办法使这个声明持久化,或者将指针设置为函数外部的 NULL 是处理事情的最佳方式?

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

如果要将实参设置为NULL,请将函数的参数类型更改为双指针并将对象的地址传递给函数。取消引用函数参数将为您提供对象,其地址作为参数传递,然后您可以在取消分配内存后将其设置为 NULL 。也就是说,以下是您需要在 object_delete() 函数中进行的更改:

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
    }
}

像这样调用object_delete()函数:

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

如果要修改指针的,那么需要给指针传递一个指针:

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

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

请注意,null-testing 指针没有太多意义,因为 free 无论如何都会这样做。

指针是值,C 是一种 pass-by-value 语言。

换句话说,object_t *obj 是传递给 object_delete 的指针的 本地副本

一个选项是另一个间接级别。

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

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