free(): double free detected in tcache の原因と直し方
同じポインタに対してfree()を2回呼び出したときに検出されるエラーです。メモリ管理システムが不整合を検知して強制終了します。
エラーメッセージの読み方
free(): double free detected in tcache 2
free(): double free detected in tcache 2- メモリ管理システム(またはassert)が不整合を検知して出したメッセージ
Aborted- この後プロセスは強制終了します(Aborted)
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main(void) { 5 int *p = malloc(sizeof(int)); 6 *p = 1; 7 free(p); 8 free(p); ^ 9 return 0; 10 }
free(): double free detected in tcache 2
Aborted
同じポインタに対してfree()を2回呼ぶと、メモリ管理システムが不整合を検知して強制終了します。解放したら即座にNULLを代入しておけば、誤って二重に解放しても検出しやすくなります(NULLに対するfree()は何もしない安全な操作です)。
直し方: free(p); を p = NULL; にします。
広告
広告スロット(未設定)
パターン2
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main(void) { 5 double *p = malloc(sizeof(double)); 6 *p = 1.5; 7 free(p); 8 free(p); ^ 9 return 0; 10 }
free(): double free detected in tcache 2
Aborted
型がdoubleでも事情は同じです。1回目のfree()の後もポインタの値自体は残っているため、「まだ使えそう」に見えるのが危険なところです。
直し方: free(p); を p = NULL; にします。
パターン3
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main(void) { 5 char *buf = malloc(16); 6 free(buf); 7 free(buf); ^ 8 return 0; 9 }
free(): double free detected in tcache 2
Aborted
解放後すぐにNULLを代入する習慣をつけておけば、コードの離れた場所で誤って再度free()されても、NULLへのfree()は無害なので事故を防げます。
直し方: free(buf); を buf = NULL; にします。
よくある誤解
1回目のfree()の後もポインタの値自体は変わらず残っているため、「まだ使えそうに見える」のが危険なところです。解放したポインタは即座にNULLを代入する習慣をつけないと、コードのどこか離れた場所で誤って2回目のfree()が呼ばれても気づけません。
まとめ
free(): double free detected in tcacheは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。