理解glibc-malloc binning实现

理解glibc-malloc binning实现,c,malloc,glibc,bins,C,Malloc,Glibc,Bins,最近我一直在研究glibc-malloc实现的内部结构。然而,关于bin索引,有一件事我似乎无法理解。因此,在malloc_状态结构中,我们有以下声明,为简洁起见,稍微格式化: struct malloc_state { /* . . Some declarations . . */ /* Set if the fastbin chunks contain recently inserted free bloc

最近我一直在研究glibc-malloc实现的内部结构。然而,关于bin索引,有一件事我似乎无法理解。因此,在malloc_状态结构中,我们有以下声明,为简洁起见,稍微格式化:

struct malloc_state
{
  /* 
       .
       .
       Some declarations
       .
       .
  */

  /* Set if the fastbin chunks contain recently inserted free blocks.  */
  /* Note this is a bool but not all targets support atomics on booleans.  */
  int have_fastchunks;

  /* Fastbins */
  mfastbinptr fastbinsY[NFASTBINS];

  /* Base of the topmost chunk -- not otherwise kept in a bin */
  mchunkptr top;

  /* The remainder from the most recent split of a small request */
  mchunkptr last_remainder;

  /* Normal bins packed as described above */
  mchunkptr bins[NBINS * 2 - 2];

  /* Bitmap of bins */
  unsigned int binmap[BINMAPSIZE];
  
  /* 
       .
       .
       Some more declarations
       .
       .
  */
};
现在我的问题是关于这个结构中的bins数组的声明。bins数组声明如下:
mchunkptr垃圾箱[NBINS*2-2]

据我所知,指向箱子的指针是使用定义如下的bin_at宏获得的:

typedef struct malloc_chunk *mbinptr;

/* addressing -- note that bin_at(0) does not exist */
#define bin_at(m, i) \
  (mbinptr) (((char *) &((m)->bins[((i) - 1) * 2]))               \
             - offsetof (struct malloc_chunk, fd))
具体来说,我的问题如下。为什么在存储箱阵列中保留的存储箱数量大约是原来的两倍?我知道有一个箱子是为调用free而产生的未排序的块保留的,并且对于已经大小排序的空闲块,有NBINS数量的箱子。然而,我不明白剩余垃圾箱的用途

我怀疑这背后有一个原因。然而,从源代码来看,我并不清楚这一点。如果你们中的任何人有一些关于为什么这样做的指导或文档,那将不胜感激


提前谢谢你

由于bin是双链接列表,每个bin头包含两个指针,而不是一个:第一个指针指向列表的头部,第二个指针指向列表的尾部。这就是为什么指针的数量是垃圾箱数量的两倍。(请注意,没有使用存储箱编号0,因此存储箱的数量实际上是
NBINS-1

正如在双链表实现中常见的那样,该列表实际上是循环的;标题可以被视为链接条目。这样就避免了在添加元素之前检查箱子是否正确的必要性。(在空箱子中,第一个和最后一个点都位于箱子头本身。)但是,
malloc_区块
中的向前(
fd
)和向后(
bk
)指针不在区块的开头。为了将bin数组中的指针对视为块条目,指针对的地址需要反向偏移
malloc\u块中
fd
指针的偏移量

图表可能会有所帮助。下面是垃圾箱中两块垃圾的外观:

     Bins Array                Chunk 0                Chunk 1 

+--> XXXXXXXXXX <-\     /--> +--------+ <-\     /--> +--------+ <-----+
|    XXXXXXXXXX    \   /     |  p_sz  |    \   /     |  p_sz  |       |
|    XXXXXXXXXX     \ /      +--------+     \ /      +--------+       |
|    XXXXXXXXXX      X       |   sz   |      X       |   sz   |       |
|    +--------+     / \      +--------+     / \      +--------+       |
|    | [2i-2] | -->/   \     |   fd   | -->/   \     |   fd   | ->+   |
|    +--------+         \    +--------+         \    +--------+   |   |
|    | [2i-1] | -->+     \<- |   bk   |          \<- |   bk   |   |   |
|    +--------+    |         +--------+              +--------+   |   |
|                  |                                              |   |
|                  +----------------------------------------------+---+
|                                                                 |
+<----------------------------------------------------------------+
bin数组块0块1
+-->XXXXXXXXX+----------++-----------/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|
|    +--------+         \    +--------+         \    +--------+   |   |

||[2i-1]|-->+\谢谢您的回复@HeapScholar:我添加了图表。希望能有帮助。这很有帮助。非常感谢您详尽的回复!