Rat*_*lle 1 c malloc free pointers
我正在读Dangling Pointer并发现这是一个好习惯,以防止自己悬挂指针错误.
free(ptr); // free the ptr
ptr = NULL;
Run Code Online (Sandbox Code Playgroud)
现在我决定用一个示例vanilla C代码来测试它.
情况1
char *ptr = malloc(10);
...
...
free(ptr);
ptr=NULL;
// Just to check what happen if I call free more than I once
free(ptr)
ptr=NULL;
Run Code Online (Sandbox Code Playgroud)
一切正常.直到我决定将它free
和指针NULL
赋值包装在一个function
我命名的中safefree
void safefree(char *pp) {
free(pp);
pp = NULL;
}
Run Code Online (Sandbox Code Playgroud)
CASE_2
现在,当我运行上面的方法超过1(像这样)
safefree(ptr);
safefree(ptr);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误.
malloc: *** error for object 0x7fd98f402910: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Run Code Online (Sandbox Code Playgroud)
我碰巧理解了错误(释放的指针没有被分配)但是我无法理解为什么它在CASE_1中没有失败并且在示例代码的后半部分失败了.
首先,让我们回顾一下这种行为free()
.引用C11
,章节§7.22.3.3
Run Code Online (Sandbox Code Playgroud)void free(void *ptr);
该
free
函数使得指向的空间ptr
被释放,即可用于进一步分配.如果ptr是空指针,则不执行任何操作.否则,如果参数与先前由内存管理函数返回的指针不匹配,或者如果通过调用free
or 释放了空间realloc
,则行为未定义.
遵循两个强调点.
NULL
以free()
只要你想多少次,它们是有效的调用(只是被忽略).free()
一次的指针.在这里,在free()
使用指针调用之后,我们明确地将指针设置为NULL
.这就是为什么,free()
在以后使用相同的指针变量调用任何数量的时间都不是问题.
C使用pass-by-value进行函数参数传递.这就是为什么,当包裹在一个函数内部时,
free(pp);
Run Code Online (Sandbox Code Playgroud)
按预期工作,(它传递所需的指针free()
)但是
pp = NULL;
Run Code Online (Sandbox Code Playgroud)
是函数的本地,并且该更改不会反映给调用者.因此,再次调用该函数会导致双重释放,就像现在一样
free()
NULL
不会反映给调用者,因此指针不会设置为NULLfree()
再次传递已经指针.如前所述,这会调用未定义的行为.
解决方案:您需要将指针作为被调用函数的参数传递给指针,safefree()
并且可以从被调用函数中设置指针值以NULL
使其反映在调用者中.就像是
void safefree(void ** ptrToPtr)
{
free(*ptrToPtr);
*ptrToPtr= NULL;
}
Run Code Online (Sandbox Code Playgroud)
和打电话一样
safefree (&ptrToBeFreed);
Run Code Online (Sandbox Code Playgroud)
将完成这项工作(请注意那里的类型,无论如何).