[英]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.