动态数组:使用realloc()避免内存泄漏

8

我使用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个可能的内存泄漏问题?
2个回答

14
如果 realloc() 失败,它会返回 NULL
所以如果您执行此操作(并假设 realloc() 会失败)
result = realloc(result, ...);

result将被赋值为NULL,并且它所指向的内容没有被释放(free()),需要被释放的地址也丢失了。

要修复这个问题,请执行以下操作:

{
  void * tmp = realloc(result, ...);
  if (NULL == tmp)
  {
    /* Handle error case, propably freeing what result is pointing to. */
  }
  else
  {
    result = tmp;
  }
}

3

解决“nulled but not freed upon failure”错误的诀窍是将realloc返回的值存储到一个单独的指针中,并在重新分配旧指针之前检查它是否为NULL

char **tmp = (char **) realloc(result, sizeof(char *) * (n + 1));
if (tmp) {
    result = tmp;
} else {
    ... // Handle reallocation error
}

现在通过使用NULL检查来保护result的赋值,您可以使用旧值:如果需要,您可以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设置为零-当前情况下,它未初始化,这是未定义的行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接