在我从前任继承的程序中,有以下格式的函数:
somefunc(some_type some_parameter, char ** msg)
换句话说,最后一个参数是char **
,用于返回消息。
即:somefunc()
将“更改”msg
。
在某些情况下,问题的变化形式如下:
sprintf(txt,"some text. Not fixed but with a format and variables etc");
LogWar("%s",txt); //call to some logging function that uses txt
*msg = strdup(txt);
我知道每次调用strdup()
都应该调用free()
来释放它分配的内存。
由于该内存用于返回某些内容,因此显然不应在somefunc()
结尾处释放。
然后呢?
如果使用相同的 msg多次调用somefunc()
,那么我认为该指针会四处移动。因此,之前的调用分配的空间将丢失,对吧?
在节目结束前的某个地方,我当然应该free(*msg)
。 (在这种情况下,*msg
是在somefunc()
调用中用作参数的版本。)
但我认为该调用只会释放最后分配的内存,而不是早期调用somefunc()
中分配的内存,对吗?
所以,我说的是somefunc()
应该是这样的:
sprintf(txt,"some text. Not fixed like here, but actually with variables etc");
LogWar("%s",txt); //call to some logging function that uses txt
free(*msg); //free up the memory that was previously assigned to msg, since we will be re-allocating it immediatly hereafter
*msg = strdup(txt);
使用free()
之前 strdup()
。
我说错了吗?
答案 0 :(得分:1)
是的,你是对的。从strdup()
返回的任何旧指针必须为free()
d才能覆盖它,否则会泄漏内存。
我确定你的清晰度在哪里简单,但我当然会投票支持这样的事情:
const char * set_error(char **msg, const char *text)
{
free(*msg);
*msg = strdup(text);
}
然后:
LogWar("%s",txt); //call to some logging function that uses txt
set_error(msg, txt);
看看我如何使用封装来使这个非常重要的序列更加明确,甚至命名?