_int_malloc
use_top:
/* 如果足够大,分割top chunk
If large enough, split off the chunk bordering the end of memory
(held in av->top). Note that this is in accord with the best-fit
search rule. In effect, av->top is treated as larger (and thus
less well fitting) than any other available chunk since it can
be extended to be as large as necessary (up to system
limitations).
top指针需要始终存在
We require that av->top always exists (i.e., has size >=
MINSIZE) after initialization, so if it would otherwise be
exhausted by current request, it is replenished. (The main
reason for ensuring it exists is that we may need MINSIZE space
to put in fenceposts in sysmalloc.)
*/
// 获取top指针,计算chunk大小
victim = av->top;
size = chunksize(victim);
// 申请的大小如果超过系统内存,报错
if (__glibc_unlikely(size > av->system_mem))
malloc_printerr("malloc(): corrupted top size");
// 如果大小超过最小大小,继续
if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE))
{
// 计算剩余大小,设置给top指针
remainder_size = size - nb;
remainder = chunk_at_offset(victim, nb);
av->top = remainder;
// 设置目标header,设置prev_inuse位
set_head(victim, nb | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
// 设置新的top指针
set_head(remainder, remainder_size | PREV_INUSE);
check_malloced_chunk(av, victim, nb);
// 计算内存地址,返回
void *p = chunk2mem(victim);
alloc_perturb(p, bytes);
return p;
}
/* When we are using atomic ops to free fast chunks we can get
here for all block sizes. */
// 当使用原子操作来释放fast chunk,我们可以获取所有块大小
else if (atomic_load_relaxed(&av->have_fastchunks))
{
malloc_consolidate(av); // 合并操作
/* restore original bin index */
if (in_smallbin_range(nb))
idx = smallbin_index(nb);
else
idx = largebin_index(nb);
}
/*
Otherwise, relay to handle system-dependent cases
否则,调用sysmalloc来处理
*/
else
{
void *p = sysmalloc(nb, av);
if (p != NULL)
alloc_perturb(p, bytes);
return p;
}
当tcachebin,fastbin,smallbin,largebin,unsortedbin都没法是用的时候哦,会来到这里进行分配内存
-
安全检查:是否大小超过系统内存,超过了报错
- 缓解 house of force 利用手法(覆盖top size,申请过大内存导致地址整数溢出,使得下一个chunk会被分配到任意地址)
-
如果大小超过最小大小
- 切割top chunk来分配新的chunk出来
-
如果使用原子操作释放fast chunk
- 堆块合并操作
-
否则,使用系统调用进行申请