簡體   English   中英

動態數組:使用 realloc() 沒有內存泄漏

[英]Dynamic arrays: using realloc() without memory leaks

我使用 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 個可能的內存泄漏?

如果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 but not freed after failure”錯誤的技巧是將realloc返回的值存儲到一個單獨的指針中,並在重新分配舊指針之前檢查它是否為NULL

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設置為零 - 目前,它未初始化,這是未定義的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM