小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


C6308 Reallocのリーク

はじめに

以下のプログラムをコード解析にかけると、C6308 Reallocのリークという警告が出力されます。

C6308 Realloc のリーク 'realloc' は null ポインターを返す可能性があります: null ポインターを、引数として 'realloc' へ渡された 'tmp' に割り当てると、元のメモリ ブロックにメモリ リークを発生させる原因となります。

#include "stdafx.h"
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
  char *tmp;

  // メモリアロケート
  tmp = (char*)malloc(100);
  if (tmp == NULL)
  {
    return 1;
  }

  //
  // 何か処理
  //

  // 再アロケート
  tmp = (char*)realloc(tmp, 100);
  if (tmp == NULL)
  {
    return 1;
  }

  // 解放
  free(tmp);
  
  return 0;
}
原因

reallocが失敗したときにtmpバッファを解放しないで、tmpにNULLを返すから最初にアロケートしたアドレスへの参照を失ってメモリリークするよということらしいです。

C6308C6308

回避方法

reallocには別の変数を渡して、実行結果が成功したことを確認した後、アドレスを入れ替えます。

#include "stdafx.h"
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
  char *tmp;
  char *tmp2;

  // メモリアロケート
  tmp = (char*)malloc(100);
  if (tmp == NULL)
  {
    return 1;
  }

  //
  // 何か処理
  //

  // 再アロケート
  tmp2 = (char*)realloc(tmp, 100);
  if (tmp2 == NULL)
  {
    return 1;
  }
  // アドレスを入れ替える(★)
  tmp = tmp2;

  //
  // 何か処理
  //

  // 解放
  free(tmp);

  return 0;
}