我是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.它没有受到伤害(因为它的旧值在被释放之后不应该被使用)并且它具有释放空指针的良好属性被指定为无操作.
但是,这样做并非万无一失.注意让其他变量别名相同的指针,因为它们仍然包含旧值,现在是一个危险的悬空指针.