从外部函数中释放指针

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_intNULL,这将导致分段错误。此外, 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 语句。如果 returnElementNULL,那么 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 的指针,引用现有元素,你应该没问题。