我正在(尝试?)返回函数内分配的内存。
假设我在这里写的内容没有明显的问题(并且没有测试),内存是如何释放或不释放的?我需要稍后free(bob)
,因为他在堆上而不是堆栈上,对吧?
我刚才在另一个公认的答案中读到了有关 C 中的引用计数的内容,但我真的真的不记得 C 有垃圾收集器之类的东西。
char* strCat5000(char *fmt, ...)
{
char buff[5000];
char *ret_;
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsnprintf(buff, sizeof(buff), fmt, arg_ptr);
va_end(arg_ptr);
//ret_ = malloc((char*)(strlen(buff)+1)*sizeof(char)); //Allocated inside function
ret_ = (char*)malloc((strlen(buff)+1)*sizeof(char)); //moved (char*) .. typo
ret_ = strcpy(ret_,buff);
return (ret_);
}
...
void findBob()
{
char * bob;
bob = strCat1000("Server is %s for %d seconds.", "on fire", 35329);
printf("%s", bob);
free(bob); //bob needs to be freed here or he'll leak when findBob ends???
}
是的。您必须在 findBob() 方法中"释放 Bob",因为否则您的程序中将没有该特定内存的进一步概念 =>您将有泄漏。所以,简而言之:是的,必须释放内存。
但是,只是旁注:这种代码非常"容易出错"。如果你有一个分配调用者应该释放的内存的函数,那么有一个freeBob()
方法或类似的方法可能是个好主意,这使得这个目的非常明显。通常,最好在同一抽象级别进行malloc()
和free()
调用。例如,在这种情况下,同一个.c文件中的两个函数可能是合理的"抽象级别"。
你是对的,如果你从函数返回堆分配的数据,它最终需要被释放(除非你需要它直到程序完成,那么你可以依赖于进程退出时释放所有内存的事实)。
引用计数是一种用于避免过早释放内存的技术。如果可以将指针复制到多个变量中,则不希望在其中任何一个变量仍在使用它时释放它。分配包含refcount
成员的结构。每次将指针分配给另一个变量时,都必须递增 refcount,以及递减该变量先前指向的任何内容的 refcount。当引用计数下降到 0 时,您可以调用 free()
。
维基百科
要处理上述问题,您有两种方法。
第一个是你正在做的事情,即在使用后free
鲍勃。因为 c 中没有automatic
任何东西。
第二个是您可以将parameter
传递给要存储结果的strCat1000
(让我们说它为 store_var
)。在这种情况下,store_var
将在堆栈上(必须在findBob
内声明),并且在findBob
结束后将自动释放。
如果你想摆脱free
,那就让你的代码免于malloc
。
这样的事情可以工作:
void findBob()
{
char store_var[1000];
strCat1000(store_var,"Server is %s for %d seconds.", "on fire", 35329);
...
void strCat1000(char to_save[],char *fmt, ...)
{
ret_ = strcpy(to_save,buff); //check for lengths also.
...
为了使它变得非常简单,我编写了以下代码(c ++)。 只需运行它并使用任务管理器监视代码内存使用情况。
#include "stdafx.h"
#include<iostream>
#include <conio.h>
using namespace std;
int * allocate(unsigned size)
{
int * arr = new int[size];
for(unsigned i=0;i<size;i++)
arr[i] = i;
return arr;
}
int main()
{
int * p;
p = allocate(1000000);
getch(); // Here you still occupy the memory
free(p); // here you free the memory you occupy in the function
getch(); // here you should see that memory is freed before returning from the main
return 0;
}