第39章 ビンのチャンク連結

ではビンがどのようにフリーチャンクを連結するのか図でも見てみましょう。

図39.1 Unsorted/Small/Large Bins

img/bins.png

配列になっているのは、連結できるチャンクのサイズが決まっており、インデックスによってどのチャンクサイズへのポインターを指すか決まっているからです。

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 に相当します。

図39.2 Large Bins

img/bins_large.png

大きめサイズの「 Large Bin 」では双方向連結リストを使って、最適なサイズを探索できるようにしています。

例では 124 が連続したら次の fd_nextsize は 256 になってますね。

Copyright 2018-2019, by Masaki Komatsu