我使用realloc来调整分配的内存:
char **get_channel_name(void)
{
char **result;
int n;
result = (char **) 0;
for (elem = snd_mixer_first_elem(handle), n = 0; elem; elem = snd_mixer_elem_next(elem)) {
if (!snd_mixer_selem_is_active(elem))
continue;
if (snd_mixer_selem_has_playback_volume(elem) &&
snd_mixer_selem_has_playback_switch(elem) &&
snd_mixer_selem_has_capture_switch(elem)) {
if (result == (char **) 0)
result = (char **) malloc(sizeof(char *));
else
result = (char **) realloc(result, sizeof(char *) * (n + 1)); /* nulled but not freed upon failure */
result[n++] = strdup(snd_mixer_selem_get_name(elem));
}
}
if (result == (char **) 0)
return NULL;
result = (char **) realloc(result, sizeof(char *) * (n + 1)); /* nulled but not freed upon failure */
result[n] = NULL;
return result;
}
当我用cppcheck工具检查代码静态C / C ++代码分析时,打印出以下警告:
Common realloc mistake: 'result' nulled but not freed upon failure
如何修复这2个可能的内存泄漏?
答案 0 :(得分:9)
如果realloc()
失败,则返回NULL
。
所以,如果你这样做(假设realloc()
会失败)
result = realloc(result, ...);
result
将被分配NULL
,其指向的内容不是free()
,且free()
的地址将丢失。
要解决此问题,请执行以下操作:
void * tmp = realloc(result, ...);
if (NULL == tmp)
{
/* Handle error case, propably freeing what result is pointing to. */
}
else
{
result = tmp;
}
答案 1 :(得分:3)
修复“已失效但未失败”错误的技巧是将realloc
返回的值存储到单独的指针中,并在重新分配旧指针之前检查NULL
:< / p>
char **tmp = (char **) realloc(result, sizeof(char *) * (n + 1));
if (tmp) {
result = tmp;
} else {
... // Handle reallocation error
}
现在result
的分配受到NULL
检查的保护,您可以使用旧值:如果您愿意,可以free
,或者您可以继续使用它如果你需要。另一方面,原始代码没有给你相同的选项。
注意:当您将NULL
指针传递给realloc
时,其行为类似于malloc
。这就是为什么你可以在第一次使用realloc
时放弃条件 - 替换这个
if (result == (char **) 0)
result = (char **) malloc(sizeof(char *));
else
result = (char **) realloc(result, sizeof(char *) * (n + 1));
用这个:
char** tmep = (char **) realloc(result, sizeof(char *) * (n + 1));
... // check temp and assign result here
不要忘记将n
设置为零 - 目前,它是未初始化的,这是未定义的行为。