第50章 free() の実装

free() を呼び出すのは「 __libc_free() 」関数をコールするのと同じことです。

5578 strong_alias (__libc_free, __free) strong_alias (__libc_free, free)

では __libc_free() の中身を確認してみましょう。

malloc.c(https://github.com/MacKomatsu/glibc/blob/release/2.27/master/malloc/malloc.c). 

3084 void
3085 __libc_free (void *mem)
3086 {
3087   mstate ar_ptr;
3088   mchunkptr p;                          /* chunk corresponding to mem */
3089
3090   void (*hook) (void *, const void *)
3091     = atomic_forced_read (__free_hook);
3092   if (__builtin_expect (hook != NULL, 0))
3093     {
3094       (*hook)(mem, RETURN_ADDRESS (0));
3095       return;
3096     }
3097
3098   if (mem == 0)                              /* free(0) has no effect */
3099     return;
3100
3101   p = mem2chunk (mem);
3102
3103   if (chunk_is_mmapped (p))                       /* release mmapped memory. */
3104     {
3105       /* See if the dynamic brk/mmap threshold needs adjusting.
3106    Dumped fake mmapped chunks do not affect the threshold.  */
3107       if (!mp_.no_dyn_threshold
3108           && chunksize_nomask (p) > mp_.mmap_threshold
3109           && chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX
3110     && !DUMPED_MAIN_ARENA_CHUNK (p))
3111         {
3112           mp_.mmap_threshold = chunksize (p);
3113           mp_.trim_threshold = 2 * mp_.mmap_threshold;
3114           LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
3115                       mp_.mmap_threshold, mp_.trim_threshold);
3116         }
3117       munmap_chunk (p);
3118       return;
3119     }
3120
3121   MAYBE_INIT_TCACHE ();
3122
3123   ar_ptr = arena_for_chunk (p);
3124   _int_free (ar_ptr, p, 0);
3125 }
3126 libc_hidden_def (__libc_free)

この中で重要なのは言うまでもなく以下の行でしょう。

3124   _int_free (ar_ptr, p, 0);

最終的には _int_free() 関数をコールしてますね。

もう一つは mmap() で割り当てた大きめのメモリー領域は munmap_chunk() 関数で解放しています。

3103   if (chunk_is_mmapped (p))                       /* release mmapped memory. */
3104     {
3105       /* See if the dynamic brk/mmap threshold needs adjusting.
3106    Dumped fake mmapped chunks do not affect the threshold.  */
3107       if (!mp_.no_dyn_threshold
3108           && chunksize_nomask (p) > mp_.mmap_threshold
3109           && chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX
3110     && !DUMPED_MAIN_ARENA_CHUNK (p))
3111         {
3112           mp_.mmap_threshold = chunksize (p);
3113           mp_.trim_threshold = 2 * mp_.mmap_threshold;
3114           LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
3115                       mp_.mmap_threshold, mp_.trim_threshold);
3116         }
3117       munmap_chunk (p);
3118       return;
3119     }

_int_free() 関数については時間の制約もあるので、次版を出すタイミングにもしかしたら説明できるかもしれません…

次版の頃には glibc-2.27 が古くなってそうですけど…

(´・ω・`)

Copyright 2018-2019, by Masaki Komatsu