CやC++をやっているのであれば誰しもが通るmalloc関数ですが、mallocにはfreeがつきものです。今回はあなたの身近でこんなメモリは解放し忘れていませんか?という例を紹介します!
ケース1
char *p1 = (char *)malloc(sizeof(char)*10);
char *p2 = (char *)malloc(sizeof(char)*15);
p1 = p2;
free(p1);
これは今p1にp2を代入している状態です。一見よさそうにも見えますが、これはつまりp1宣言時に確保されたメモリが、誰からも刺されてないポインタの状態になっています。
こうなるとメモリは適切に解放されないため、リークエラーが発生します。
じゃあどうする?
上記のようなケースに当たることは少ないかもしれませんが、代入する前に一度他の変数に置くようにするなどが有効です。
char *p1 = (char *)malloc(sizeof(char)*10);
char *p2 = (char *)malloc(sizeof(char)*15);
char *tmp = p1;
p1 = p2;
free(tmp);
free(p1);
こうすることによって未解放のメモリが発生する事を防ぐことができます。
ケース2
ケース2は二次元配列のメモリ解放です。これは割と有名かもしれませんが、意外とfreeした気になるので注意が必要です!
例えば以下のケース
static int ft_free(char **ans, int len)
{
while (len > 0)
{
free(ans[len]);
len--;
}
return (-1);
}
これではメモリリークが発生します。ちゃんとwhileを回してfreeしているのに何が悪いのでしょう?
そう親元のans配列自体をfreeし忘れていることになります。
つまり先ほどのコードは
static int ft_free(char **ans, int len)
{
while (len > 0)
{
free(ans[len]);
len--;
}
free(ans);
return (-1);
}
とするのが正しいでのです。
mallocは先頭アドレスを返しているという事は意外と忘れられがちなので、覚えておきましょう!
Comments
引数
len
に1
が与えられた場合ans[1]
がfree
されますが正しいですか?Let's comment your feelings that are more than good