CentOS malloc 的数据结构

C语言中malloc的实现其实不是在CentOS层面,而是在编译器层面做的。
理解gcc的malloc实现,需要阅读glibc的源码,关键部分摘录如下:

 struct malloc_state {
/* Serialize access. */
mutex_t mutex;

/* Flags (formerly in max_fast). */
int flags;

/* 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];

/* Linked list */
struct malloc_state *next;

/* Linked list for free arenas. */
struct malloc_state *next_free;

/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
INTERNAL_SIZE_T attached_threads;

/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};

# 获取源代码
debuginfo-install glibc

/**
* malloc/malloc.c
* 仅摘录关键代码
*/

struct malloc_chunk {
/* Size of previous chunk (if free). */
INTERNAL_SIZE_T prev_size;
/* Size in bytes, including overhead. */
INTERNAL_SIZE_T size;

/* double links -- used only if free. */
struct malloc_chunk* fd;
struct malloc_chunk* bk;

/* Only used for large blocks: pointer to next larger size. */
/* double links -- used only if free. */
struct malloc_chunk* fd_nextsize;
struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mbinptr;

void*__libc_malloc(size_t bytes){
// ...
void *victim;
// ...
victim = _int_malloc(ar_ptr, bytes);
// ...
return victim;
}

static void*
_int_malloc(mstate av, size_t bytes)
{
// ...
checked_request2size(bytes, nb);
// ...
if (in_smallbin_range(nb)) { // <= 1024,相关宏见下方
idx = smallbin_index(nb); // nb / 16 + 0 相关宏见下方
bin = bin_at(av,idx);
if ( (victim = last(bin)) != bin) {
if (victim == 0) malloc_consolidate(av);
// ...
}
// ...
for(;;) {
while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
// ...
}

use_top:
// ...
else {
void *p = sysmalloc(nb, av);
if (p != NULL)
  alloc_perturb (p, bytes);
// ... return p;
}
}
}

static void malloc_consolidate(mstate av)
{
if (get_max_fast () != 0) {
// ...
}
else {
malloc_init_state(av);
// ...
}
}

static void malloc_init_state(mstate av)
{
for (i = 1; i < NBINS; ++i) {
bin = bin_at(av,i);
bin->fd = bin->bk = bin;
}


static void* sysmalloc(INTERNAL_SIZE_T nb, mstate av)
{
old_top = av->top;
old_size = chunksize(old_top);

}
// 公用宏
#define INTERNAL_SIZE_T size_t
#define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
#define NSMALLBINS 64
#define MIN_LARGE_SIZE ((NSMALLBINS - SMALLBIN_CORRECTION) * SMALLBIN_WIDTH)

// in_smallbin_range 相关宏
#define in_smallbin_range(sz) \
((unsigned long)(sz) < (unsigned long)MIN_LARGE_SIZE)

// smallbin_index 相关宏
#define smallbin_index(sz) \
((SMALLBIN_WIDTH == 16 ? (((unsigned)(sz)) >> 4) : (((unsigned)(sz)) >> 3)) \
+ SMALLBIN_CORRECTION)

// bin_at相关宏
#define bin_at(m, i) \
(mbinptr) (((char *) &((m)->bins[((i) - 1) * 2]))      \
   - offsetof (struct malloc_chunk, fd))

参考:

http://blog.leanote.com/post/3191220142@qq.com/Linux%E5%A0%86%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86-3

——————————————
2019年03月25日21:08:55更新:

# 查看glibc版本
ldd --version
2.17
git checkout release/2.17/master
参考:
https://blog.csdn.net/conansonic/article/details/50121589
https://www.oschina.net/question/2471135_2133942

发表评论

电子邮件地址不会被公开。 必填项已用*标注