如何释放从另一个函数返回的char *?

时间:2014-03-28 20:07:52

标签: c memory-leaks malloc free

我们假设我们有以下情况。

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] = '\0';
    return output;
}

int main() {
    char* input = "Hello";
    char* output = halfString(input);
    printf("%s\n",output);
    free(output);
} 

呼叫&#34;免费(输出)&#34;释放char *输出的内存为main并释放char *输出本地的内存到halfString()?或者,half * String()本地的char *输出是否仍有内存泄漏?

感谢任何帮助。

6 个答案:

答案 0 :(得分:2)

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

halfString()函数中,您分配一个缓冲区,并将该缓冲区的地址(指针)存储在本地output中。然后将其返回给调用者{{1}巧合地,它有一个同名的变量,它将指向同一个缓冲区。

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

现在关于你的问题&#34;是否有内存泄漏?&#34; - 您已经将malloc设置为单个缓冲区,然后您释放相同的缓冲区,因此没有链接。始终将malloc与免费配对,并且你的状态良好。

答案 1 :(得分:2)

代码大多是正确的,因为malloc()将内存放在堆上,free()释放它。它们被调用的函数无关紧要。

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

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

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

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

算法复杂度

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

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

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

// Version 1
size_t i, n = strlen(input);
for (i = 0; i < n; i++)
    ...

// Version 2
size_t i;
for (i = 0; input[i] != '\0'; i++)
    ...

答案 2 :(得分:2)

没有内存泄漏。

但是,您似乎对堆分配如何工作感到困惑。这里只分配了一个内存块,并且它不是&#34; local&#34;到halfString()main()。分配的块存在于堆中,并且不限定为特定的代码块。

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

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

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

答案 3 :(得分:0)

free()将释放在被调用函数本身中分配的内存。它不是任何函数的本地因为malloc allocates memory on heap 您调用local memory的内容在stack上,当函数返回时将被释放 那么使用malloc完成的分配是在heap上进行的,并且您使用的过程将释放在被调用函数中分配的内存。

答案 4 :(得分:0)

此代码将正常工作(如果其他人提及的一个错误修复)。 main中的调用将释放halfString中分配的内存。

没有“主要输出的输出内存”。 main的本地内容是输出指针,它在堆栈上分配,并在主要退出时超出范围。

答案 5 :(得分:0)

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