C语言 如何释放从另一个函数返回的字符*



假设我们有以下情况。

char* halfString(char* input) {
    char* output = malloc(strlen(input));
    int i = 0;
    for(i = 0; i < strlen(input); i++)
        output[i] == input[i];
    output[i] = '';
    return output;
}
int main() {
    char* input = "Hello";
    char* output = halfString(input);
    printf("%sn",output);
    free(output);
} 

调用 "free(output(" 是否会释放 main 本地的 char* 输出内存,并释放 halfString(( 本地的 char* 输出的内存?或者 halfString(( 本地的 char* 输出是否仍然存在内存泄漏?

任何帮助,不胜感激。

没有内存泄漏。

但是,您似乎对堆分配的工作原理感到困惑。这里只分配了一块内存,它不是halfString()main()的"本地"。分配的区块存在于堆中,并且不限定为特定代码块。

malloc()返回指向它的指针。然后,您将该指针返回到 main() ,但指针的值仍然相同:它指向内存中的相同地址,相同的堆块。 然后main()正确地释放它。

作为设计考虑,这通常不是最好的做法。通常,调用方不一定知道 halfString() 返回的指针指向分配了malloc()的块,并且他们需要free()该块。这必须非常清楚和仔细地记录在案。更好的解决方案可能是提供一个执行释放的freeHalfString()函数;然后,从维护的角度来看,这两个函数可以放在同一个位置并同时维护,这样调用方就不必担心缓冲区是如何分配的,或者如何释放它。

(正如其他人指出的那样,您也有缓冲区溢出,因为您需要分配 strlen(input) + 1 个字节来包含 NULL 终止符。

代码大多是正确的,因为malloc()将内存放在堆上并free()释放它。 从哪个函数调用它们并不重要。

也就是说,有一个重要的逐一错误:

char* output = malloc(strlen(input) + 1); // Don't forget +1

strlen() 函数返回字符串中的字符数,不包括终止符。

这些错误通常可以通过使用某些工具自动捕获,例如Mudflap(如果使用GCC则使用-fmudflap编译(和Valgrind。

算法复杂性

代码的算法复杂性存在问题,当启用优化时,使用好的编译器可能会消失。

for(i = 0; i < strlen(input); i++)

这将调用 strlen() ,即 O(N(,它将调用 strlen() O(N( 次,给出 O(N2( 渐近性能。 我们可以做得更好,这里有两个修复:

// Version 1
size_t i, n = strlen(input);
for (i = 0; i < n; i++)
    ...
// Version 2
size_t i;
for (i = 0; input[i] != ''; i++)
    ...

您似乎混淆了两个相关项目:缓冲区和指针。缓冲区是一个内存块,在您的问题的上下文中,它是使用 malloc() 分配的。指针是相关的,因为它指向缓冲区,但它不是缓冲区本身。

halfString() 函数中,分配缓冲区,并将该缓冲区的地址(指针(存储在本地output中。然后,您将它返回给调用方 main() ,恰好该调用方具有指向同一缓冲区的同名变量。

现在,在 main() 中,当您free(output);不是在释放指针时,您是在释放指针指向的缓冲区。缓冲区的分配位置无关紧要,重要的是缓冲区已分配(并且尚未释放(。在此调用之后,main 函数的 output 变量仍然存在,并且它仍然具有曾经有效缓冲区的地址 - 但当然不能使用该缓冲区,因为它不再有效。

现在关于你的问题"是否存在内存泄漏?"——你已经错误地分配了一个缓冲区,然后你释放了同一个缓冲区,所以没有链接。始终正确配对 malloc 和自由,您将保持良好状态。

free()将释放在被调用函数本身中分配的内存。 它不是任何函数的本地,因为malloc allocates memory on heap .
您称之为 local memory 的内容位于函数返回时将被释放的stack上。
因此,使用 malloc 完成的分配heap,您使用的过程将释放在调用函数中分配的内存。

此代码将正常工作(如果其他人提到的 off-byone 错误已修复(。 main 中的调用将释放 halfString 中分配的内存。

没有"主输出本地内存"。 main 的本地是输出指针,它是在堆栈上分配的,当 main 退出时将超出范围。

没有内存泄漏。系统知道有多少内存与指针相关联,并且由于您无法释放分配的malloc的部分内存块,因此它将释放所有内存块。

相关内容

  • 没有找到相关文章

最新更新