我们假设我们有以下情况。
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 *输出是否仍有内存泄漏?
感谢任何帮助。
答案 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的部分内存块,所以它将释放所有内存。