简体   繁体   English

在 Function 中设置指向“NULL”的指针,并使其在 C 中保持“NULL”

[英]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 (ie a series of standard constructors, destructors, etc.) like so:我对 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;
    }
}

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.不过,我似乎在制作析构函数式 function 时遇到问题,因为在释放它后我无法将 function 的参数设置为NULL I am fairly sure this has to do with the fact that data declared on the stack in a callable object is impersistent.我相当确定这与以下事实有关:在可调用 object 中在堆栈上声明的数据是非持久性的。 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?有没有办法使这个声明持久化或者将指针设置为NULL之外的 NULL 是处理事物的最佳方式?

I am unable to set the argument of the function to NULL after freeing it...释放后我无法将 function 的参数设置为 NULL ...

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:如果要将参数设置为NULL ,请将 function 的参数类型更改为双指针并将 object 的地址传递给 function。取消引用 function 参数将为您提供 object,然后您可以将其地址传递给 888,然后将其参数传递给释放NULL后变为 NULL。也就是说,以下是您需要在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:像这样调用object_delete() function:

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

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.请注意,对指针进行空测试没有多大意义,因为无论如何free都会这样做。

Pointers are values, and C is a pass-by-value language.指针是值,C 是一种按值传递的语言。

In other words, object_t *obj is a local copy of the pointer passed to object_delete .换句话说, object_t *obj是传递给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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM