Code Fix

上級

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パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)