我写了一个使用堆栈ADT的程序。
main 创建一个新堆栈,同时为用户提供 3 个函数:
Stack my_stack = sCreate (copy_int, free_int, print_int);
当我调用"窥视"函数时:
printf ("Peek: |%d|nn", *(int*)sPeek(my_stack));
我有内存泄漏。
速览函数如下所示:
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(?
Element e = sPeek(my_stack);
if (e) {
printf ("Peek: |%d|nn", *(int*)e);
}
free(e);
似乎有点明显,所以不确定这是否是你的意思。
在最后一个代码片段中,您在检查 malloc
的返回值之前使用了 *new_int
。如果new_int
NULL
,这将导致分段错误。此外,if/else
完全没有书面价值。这四行可以替换为return new_int;
,在任何情况下行为都不会改变。最后,不要从 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;
}
最后,对于您的问题,除非您保留该指针的副本并在完成它时将其free
,否则copy_int
返回的内存将被泄漏。此外,如果将 NULL 指针传递给 printf
,则会请求另一个分段错误。所以printf
行需要用这段代码替换(假设Element
真的void *
(
int *value = sPeek(my_stack);
if (value)
printf ("Peek: |%d|nn", *value);
free(value);
如何从copy_int释放指针(malloc(?
如果您不再需要它,只需致电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
。您要删除它。
任何返回使用后未自动释放的资源的函数都必须具有如何释放资源的文档。在malloc()
的情况下,它被记录为free()
,fopen()
它是fclose()
等。
当你自己创建一个函数时,你可以引用free()
,如果你返回一个指针,你又从malloc()
接收。如果您有更复杂的设置,则可能必须创建自己的函数。
查看您的函数,您使用 malloc()
分配内存,然后分配给内存(或者如果分配失败,则炸毁,您验证为时已晚(,然后准确返回从 malloc()
收到的指针。因此,您返回的资源可以(并且必须!(随free()
一起释放。
顺便说一句:考虑不要不必要地复制东西。你对copy_int()
的调用对我来说似乎是多余的,只需返回一个指向 const int 的指针,引用现有元素,你应该没问题。