函数asprintf()和vasprintf()是sprintf(3)和vsprintf(3)的类似函数,除了它们分配一个足够大的字符串来保存包括终止空字节的输出,并通过第一个参数返回指向它的指针.应该将此指针传递给free(3)以在不再需要时释放已分配的存储.
这是我的C代码
void function(){
char *out = NULL;
int parts[16] = {1,2,05,003};
asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
// free(out);
}
int main(void){
function();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当在调试模式下监视该函数时,我看到该变量在从函数返回时已被销毁.为什么我不需要free()上面的代码?
你能告诉我在什么情况下asprintf我需要免费使用吗?
顺便说一句,我有"gcc版本4.7.2(Ubuntu/Linaro 4.7.2-2ubuntu1)"

unw*_*ind 10
你需要打电话free().
变量离开了作用域,因此变量的实际值(free()需要的地址)在该点丢失,从而产生内存泄漏.
该free()函数对先前由其返回的内存地址malloc() 或其他堆分配调用感兴趣,而在您的特定变量中根本不感兴趣.
你可以这样做:
char *out = NULL, *a, *b, *c, *d, *e;
int parts[16] = {1,2,05,003};
asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
a = b = c = d = e = out;
Run Code Online (Sandbox Code Playgroud)
而且只有五个变量保存同一地址的副本超出范围.当然,堆子系统(通过malloc()/ free()calls 到达)对此一无所知.
你能告诉我在什么情况下我需要免费使用asprintf吗?
每次,除非asprintf返回-1.
如果无法进行内存分配,或者发生其他错误,这些函数将返回-1,并且内容
strp未定义.
例如,您可以分析valgrind输出.
free电话:== 3711 == HEAP SUMMARY:
== 3711 ==在退出时使用:1个块中的8个字节
== 3711 ==总堆使用量:2个分配,1个释放,108个字节分配
显然,存在内存泄漏.
free电话:== 3722 == HEAP SUMMARY:
== 3722 ==在退出时使用:0个字节中的0个字节
== 3722 ==总堆使用量:2个分配,2个释放,分配108个字节
看起来你不太明白什么是指针,什么是局部变量,以及分配内存的作用.
在你的function()你有一个变量out.你已经声明它是一个char指针.
您正在将指向该变量的指针传递给asprintf().这样asprintf可以在堆上分配一些内存,并存储该内存位置的地址out.这称为"指针指针",为什么签名asprintf()显示为asprintf(char **ret, .. )- 注意双精度**
out现在包含已分配内存的地址.然后你离开function().out不再存在,因为它是一个局部变量,只存在于堆栈中.之前包含在其中的地址已丢失,但在堆上分配的内存仍然已分配...并且您有内存泄漏.
free()在丢失地址之前,你需要那个记忆,它将永远超出你的范围.