从外部函数中释放指针
Free a pointer from an external function
我编写了一个使用堆栈 ADT 的程序。
main 创建一个新堆栈,同时提供 3 个函数供用户使用:
Stack my_stack = sCreate (copy_int, free_int, print_int);
当我调用 'peek' 函数时:
printf ("Peek: |%d|\n\n", *(int*)sPeek(my_stack));
我有内存泄漏。
peek 函数如下所示:
Element sPeek (Stack stack){
if ((NULL == stack) || (0 >= stack->used_places))
return NULL;
Element returnElement = stack->copy_function(stack->stack_array[stack->used_places-1]);
if (NULL == returnElement){
free (returnElement);
return NULL;
}
return returnElement;
可能是因为那里调用了copy_function,也就是用户给的copy_int:
Element copy_int (Element element){
int *new_int = (int*) malloc(sizeof(int*));
*new_int = *(int*)element;
if (NULL != new_int)
return new_int;
else
return NULL;
如何从 copy_int 释放指针 (malloc)?
How do I release the pointer (malloc) from copy_int?
如果您不再需要它,只需调用 free()
即可。
也在这里
int * new_int = (int*) malloc(sizeof(int*));
*new_int = *(int*)element;
if (NULL != new_int)
return new_int;
else
return NULL;
NULL
的测试应该在取消引用指针 element
之前完成:
int *new_int = malloc(sizeof(int*));
if (NULL != new_int)
{
*new_int = *(int*)element;
return new_int;
}
else
return NULL;
注意:在 C 中不需要强制转换 malloc/calloc/realloc
的结果,也不以任何方式推荐。
还有 ^2 在此处调用 free()
:
if (NULL == returnElement){
free (returnElement);
return NULL;
}
是用的少,至于free()
没有什么用,至于returnElement
指向无处b携带NULL
。你想删除它。
Element e = sPeek(my_stack);
if (e) {
printf ("Peek: |%d|\n\n", *(int*)e);
}
free(e);
看起来有点明显,所以不确定这是否是您的意思。
在最后一个代码片段中,您在检查 malloc
中的 return 值之前使用了 *new_int
。如果 new_int
是 NULL
,这将导致分段错误。此外, if/else
完全没有价值。这四行可以用 return new_int;
替换,在任何情况下都绝对不会改变行为。最后,don't cast the return value from malloc.
所有这些问题都已解决,最后的代码片段如下所示
Element copy_int (Element element)
{
int *new_int = malloc(sizeof(int));
if ( new_int )
*new_int = *(int*)element;
return new_int;
}
在 sPeek
函数中,您有一个类似的毫无价值的 if
语句。如果 returnElement
是 NULL
,那么 free
就没什么了。所以sPeek
函数应该是
Element sPeek (Stack stack)
{
if ( stack && stack->used_places > 0 )
return stack->copy_function(stack->stack_array[stack->used_places-1]);
else
return NULL;
}
最后关于你的问题,由 copy_int
编辑的内存 return 将 泄漏,除非你保留该指针的副本,并且 free
当你完成它时。此外,如果您将 NULL 指针传递给 printf
,您会要求另一个分段错误。所以printf
行需要换成这段代码(假设Element
真的是void *
)
int *value = sPeek(my_stack);
if (value)
printf ("Peek: |%d|\n\n", *value);
free(value);
任何return使用后不会自动释放资源的函数都必须有如何释放资源的文档。在 malloc()
的情况下,它被记录为 free()
,对于 fopen()
,它被记录为 fclose()
等
当你自己创建一个函数时,你可以,例如参考 free()
,如果你 return 一个你又从 malloc()
收到的指针。如果您有更复杂的设置,您可能需要创建自己的函数。
查看你的函数,你使用 malloc()
分配内存,然后分配给内存(或者如果分配失败则爆炸,你验证得太晚了),然后 return 恰好是指针从 malloc()
收到。因此,您正在 return 可以(并且必须!)使用 free()
释放的资源。
顺便说一句:考虑不要复制不必要的东西。你对 copy_int()
的调用对我来说似乎是多余的,只是 return 指向 const int 的指针,引用现有元素,你应该没问题。
我编写了一个使用堆栈 ADT 的程序。
main 创建一个新堆栈,同时提供 3 个函数供用户使用:
Stack my_stack = sCreate (copy_int, free_int, print_int);
当我调用 'peek' 函数时:
printf ("Peek: |%d|\n\n", *(int*)sPeek(my_stack));
我有内存泄漏。
peek 函数如下所示:
Element sPeek (Stack stack){
if ((NULL == stack) || (0 >= stack->used_places))
return NULL;
Element returnElement = stack->copy_function(stack->stack_array[stack->used_places-1]);
if (NULL == returnElement){
free (returnElement);
return NULL;
}
return returnElement;
可能是因为那里调用了copy_function,也就是用户给的copy_int:
Element copy_int (Element element){
int *new_int = (int*) malloc(sizeof(int*));
*new_int = *(int*)element;
if (NULL != new_int)
return new_int;
else
return NULL;
如何从 copy_int 释放指针 (malloc)?
How do I release the pointer (malloc) from copy_int?
如果您不再需要它,只需调用 free()
即可。
也在这里
int * new_int = (int*) malloc(sizeof(int*));
*new_int = *(int*)element;
if (NULL != new_int)
return new_int;
else
return NULL;
NULL
的测试应该在取消引用指针 element
之前完成:
int *new_int = malloc(sizeof(int*));
if (NULL != new_int)
{
*new_int = *(int*)element;
return new_int;
}
else
return NULL;
注意:在 C 中不需要强制转换 malloc/calloc/realloc
的结果,也不以任何方式推荐。
还有 ^2 在此处调用 free()
:
if (NULL == returnElement){
free (returnElement);
return NULL;
}
是用的少,至于free()
没有什么用,至于returnElement
指向无处b携带NULL
。你想删除它。
Element e = sPeek(my_stack);
if (e) {
printf ("Peek: |%d|\n\n", *(int*)e);
}
free(e);
看起来有点明显,所以不确定这是否是您的意思。
在最后一个代码片段中,您在检查 malloc
中的 return 值之前使用了 *new_int
。如果 new_int
是 NULL
,这将导致分段错误。此外, if/else
完全没有价值。这四行可以用 return new_int;
替换,在任何情况下都绝对不会改变行为。最后,don't cast the return value from malloc.
所有这些问题都已解决,最后的代码片段如下所示
Element copy_int (Element element)
{
int *new_int = malloc(sizeof(int));
if ( new_int )
*new_int = *(int*)element;
return new_int;
}
在 sPeek
函数中,您有一个类似的毫无价值的 if
语句。如果 returnElement
是 NULL
,那么 free
就没什么了。所以sPeek
函数应该是
Element sPeek (Stack stack)
{
if ( stack && stack->used_places > 0 )
return stack->copy_function(stack->stack_array[stack->used_places-1]);
else
return NULL;
}
最后关于你的问题,由 copy_int
编辑的内存 return 将 泄漏,除非你保留该指针的副本,并且 free
当你完成它时。此外,如果您将 NULL 指针传递给 printf
,您会要求另一个分段错误。所以printf
行需要换成这段代码(假设Element
真的是void *
)
int *value = sPeek(my_stack);
if (value)
printf ("Peek: |%d|\n\n", *value);
free(value);
任何return使用后不会自动释放资源的函数都必须有如何释放资源的文档。在 malloc()
的情况下,它被记录为 free()
,对于 fopen()
,它被记录为 fclose()
等
当你自己创建一个函数时,你可以,例如参考 free()
,如果你 return 一个你又从 malloc()
收到的指针。如果您有更复杂的设置,您可能需要创建自己的函数。
查看你的函数,你使用 malloc()
分配内存,然后分配给内存(或者如果分配失败则爆炸,你验证得太晚了),然后 return 恰好是指针从 malloc()
收到。因此,您正在 return 可以(并且必须!)使用 free()
释放的资源。
顺便说一句:考虑不要复制不必要的东西。你对 copy_int()
的调用对我来说似乎是多余的,只是 return 指向 const int 的指针,引用现有元素,你应该没问题。