7

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 つのメモリ リークの可能性を修正するにはどうすればよいですか?

4

2 に答える 2

13

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;
  }
}
于 2014-12-21T13:37:53.073 に答える
3

「nulled but not freed on 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。現在、初期化されていない状態で使用されており、これは未定義の動作です。

于 2014-12-21T13:39:04.007 に答える