动态数组:使用realloc()而不会出现内存泄漏

我使用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 

如何修复这两个可能的内存泄漏?

如果realloc()失败,则返回NULL

所以,如果你这样做(假设realloc()会失败)

 result = realloc(result, ...); 

result将被指定为NULL ,它指向的内容不是free() ed,而free() ed的地址将丢失。

解决这个问题:

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

修复“nulled但未释放失败”错误的技巧是将realloc返回的值存储到单独的指针中,并在重新分配旧指针之前检查它是否为NULL

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

现在结果的赋值受到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设置为零 – 目前,它是未初始化的,这是未定义的行为。