在返回函数之前释放已分配的内存

15

我正在尝试在一个函数中使用malloc返回一个数组:

char* queueBulkDequeue(queueADT queue, unsigned int size)
{
    unsigned int i;
    char* pElements=(char*)malloc(size * sizeof(char));
    for (i=0; i<size; i++)
    {
        *(pElements+i) = queueDequeue(queue);
    }
    return pElements;
}
问题是我需要释放它,因为我的MCU堆大小是有限的。但我想要返回它,所以我不能在函数中释放它,对吗?那么我能否在函数外部(调用函数的地方)释放已分配的内存?这方面是否有最佳实践?提前谢谢!

3
你需要在函数外释放它。无论如何,malloc分配的内存并没有要求必须在函数内部释放。 - futureelite7
当然可以。这正是malloc的全部意义所在。如果不能做到这一点,那么就没有理由创建malloc了。 - R.. GitHub STOP HELPING ICE
4个回答

11

由于malloc()分配的内存位于堆上而不是栈上,因此可以在无论哪个函数中都可以访问它。如果您想传递由malloc()分配的内存,则除了从调用者中释放它之外,没有其他选择。(按引用计数术语,这被称为所有权转移。)


很好的解释。 - George

10

1) 是的,您可以在函数外部free() malloc分配的内存。

2) 不,您不能在函数内部释放它并将数据传递到函数外部,因此您必须在这里执行1)。

3) 如果您担心内存不足,您需要始终检查内存分配失败,您未能在此处执行此操作,这可能会导致段错误。


1
......或者更糟,在嵌入式系统中出现段错误。 - Greg Hewgill
是的,当你在函数外释放了一个malloc分配的内存时,我确实关心这个问题。你该如何解决它? - KiL
@KiL,“修复”的方法是处理内存分配例程无法分配所需内存并优雅地失败的情况,而不是由空指针破坏执行的任何线程控制。 - tbert

9
当然,你可以在函数外部释放分配给某个函数的内存,前提是你必须返回该内存。但是,另一种选择是修改你的函数如下,让调用者分配和释放该内存。这将符合为内存分配而负责释放内存的函数概念。
void queueBulkDequeue(queueADT queue, char *pElements, unsigned int size) 
{     
   unsigned int i;     
   for (i=0; i<size; i++)     
   {         
      *(pElements+i) = queueDequeue(queue);     
   }     
   return; 
} 

//在调用者中

char *pElements = malloc(size * sizeof(char));
queueBulkDequeue(queue, pElements, size);
//Use pElements
free(pElements);

5

是的,您可以在调用函数外部释放分配的内存;这正是您在此情况下需要做的。

替代方案包括将缓冲区及其长度传递到函数中,并将实际长度返回给调用者,就像fgets一样。这可能不是最佳的替代方案,因为调用者需要在循环中调用您的函数。


请给出降分的原因,谢谢。 - Sergey Kalinichenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接