ではビンがどのようにフリーチャンクを連結するのか図でも見てみましょう。
配列になっているのは、連結できるチャンクのサイズが決まっており、インデックスによってどのチャンクサイズへのポインターを指すか決まっているからです。
Fast Bin を除くと全て bins 配列におけるフリーリストとなります。
デバッグ時に確認をしやすいのが Unsorted Bin (未整理のチャンクのビン)ですね。
これはサイズ関係無しに使われます。
malloc.c(https://github.com/MacKomatsu/glibc/blob/release/2.27/master/malloc/malloc.c).
1389 typedef struct malloc_chunk *mbinptr; 1390 1391 /* addressing -- note that bin_at(0) does not exist */ 1392 #define bin_at(m, i) \ 1393 (mbinptr) (((char *) &((m)->bins[((i) - 1) * 2])) \ 1394 - offsetof (struct malloc_chunk, fd)) //略 1523 /* The otherwise unindexable 1-bin is used to hold unsorted chunks. */ 1524 #define unsorted_chunks(M) (bin_at (M, 1))
この中で重要なのは bins[] 配列の解釈方法です。
1393 (mbinptr) (((char *) &((m)->bins[((i) - 1) * 2])) \
まあここで重要なパラメーターは i となります。
i はビンのインデックスを指すため 0 は存在しないとのことです。
i == 1 の場合には bins[0] となります。
bins_at(m, 1) => bins[0]
i == 2 の場合には bins[2] となります。
bins_at(m, 2) => bins[2]
さらに i == 3 の場合には bins[4] となります。
bins_at(m, 3) => bins[4]
このように bin[] 配列の中のインデックスは 2 の倍数となります。
これは bin[] 配列には fw と bd の2つのポインターがあるからで、2 個の要素が必要となるからです。
Bin 1 は bins_at(m,1) の評価であるため bins[0] が Unsorted bin に相当します。
大きめサイズの「 Large Bin 」では双方向連結リストを使って、最適なサイズを探索できるようにしています。
例では 124 が連続したら次の fd_nextsize は 256 になってますね。
Copyright 2018-2019, by Masaki Komatsu