什么时候在C中释放指针以及如何知道它是否被释放

xam*_*mbo 14 c

我是C的新手,试图找出C中的内存分配,我有点困惑

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

typedef struct
{
    int a;
} struct1_t;

int main()
{
    funct1(); //init pointer
    return 1;
}


int funct2(struct1_t *ptr2struct)
{
    printf("print a is %d\n",ptr2struct->a);
    //free(ptr2struct);
    printf("value of ptr in funct2 is %p\n", ptr2struct);
    return 1; //success
}


int funct1(){

    struct1_t *ptr2struct = NULL;
    ptr2struct = malloc(sizeof(*ptr2struct));
    ptr2struct->a = 5;
    printf("value of ptr before used is %p", ptr2struct);
    if (funct2(ptr2struct) == 0) {
        goto error;
    }
    free(ptr2struct);

    printf("value of ptr in funct1 after freed is is %p\n", ptr2struct);
    return 1;

error:
    if(ptr2struct) free(ptr2struct);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我有功能1调用功能2,并在使用funct1中的分配指针后,我尝试释放指针.我创建了一个案例,如果funct2中的返回值不是1,则再次尝试释放指针.

我的问题如下

哪个练习更好,如果我应该释放funct2中的内存(在我传递之后)或funct1中(在我完成获取funct1的返回值之后)第二个问题是这是否正确产生goto错误,并且错误:

if(ptr2struct) free(ptr2struct); 
Run Code Online (Sandbox Code Playgroud)

我的第三个问题是,如何检查分配的值是否已经释放?因为在获得返回值之后,我释放指针,但是如果我打印它,它显示与分配的一个相同的位置(所以不是空指针).

MK.*_*MK. 14

在指针上调用free()不会改变它,只将内存标记为空闲.您的指针仍将指向包含相同值的相同位置,但该值现在可以随时被覆盖,因此在释放后不应使用指针.为了确保这一点,最好在释放它之后始终将指针设置为NULL.


hug*_*omg 11

1)我应该在调用函数或被调用函数中释放它吗?

我尝试在与malloc-ing相同的功能中进行自由.这样可以将内存管理问题保存在一个地方,并且可以更好地分离关注点,因为在这种情况下,被调用的函数也可以使用未被malloc编辑的指针或两次使用相同的指针(如果你想这样做) ).

2)做"转到错误"是否正确?

是! 通过跳转到函数末尾的单个位置,您可以避免复制资源释放代码.这是一种常见的模式,并没有那么糟糕,因为"goto"只是作为一种"返回"声明,并没有做任何它更为人所知的棘手和邪恶的东西.

//in the middle of the function, whenever you would have a return statement
// instead do
return_value = something;
goto DONE;

//...

DONE:
    //resorce management code all in one spot
    free(stuff);
    return return_value;
Run Code Online (Sandbox Code Playgroud)

另一方面,C++有一种巧妙的方法来进行这种资源管理.由于析构函数在函数退出之前被确定性地调用,因此它们可以用来巧妙地打包这个资源管理之王.他们称这种技术为RAII

其他语言必须处理的另一种方法是终止块.

3)我可以看看指针是否已被释放?

可悲的是,你做不到.有些人在释放它之后将指针变量值设置为NULL.它没有受到伤害(因为它的旧值在被释放之后不应该被使用)并且它具有释放空指针的良好属性被指定为无操作.

但是,这样做并非万无一失.注意让其他变量别名相同的指针,因为它们仍然包含旧值,现在是一个危险的悬空指针.

  • 如果你可以在同一个函数中分配和释放,也许你应该将它保留在堆栈中. (8认同)