当我们调用malloc时先到libc函数中调用libc_malloc,__libc_malloc会先调用malloc_hook_init进行初始化,然后返回__libc_malloc,这时候会执行_init_malloc开始分配内存 ,定义在malloc.c中
我来分段分析
1
Void_t* public_mALLOc(size_t bytes) {
mstate ar_ptr;
Void_t *victim;
__malloc_ptr_t (*hook) (size_t, __const __malloc_ptr_t) =force_reg(__malloc_hook); if (__builtin_expect (hook != NULL, 0)) //如此可以发现检查了hook函数是否为空
return (*hook)(bytes, RETURN_ADDRESS (0)); //如果不是空就是调用这个函数
这里首先会检车hook函数是否为NULL如果存在就调用并返回不存在就继续执行
2
arena_lookup(ar_ptr);//在main_arena段寻找分配区指针
arena_lock(ar_ptr, bytes);
if(!ar_ptr) //找到就会调用_int_malloc()函数
return 0; //没找到就返回
victim = _int_malloc(ar_ptr, bytes);
这里就是在寻找分配区指针找到就调用_int_malloc函数分配内存没有就结束malloc函数
if(!victim) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
victim = _int_malloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
这个是假如调用了_int_malloc函数但是没有分配内存且不是在主分配区就会如果主分配区还能分配就会再次尝试从主分配区分配内存,首先释放分配区的锁然后拿到锁再次调用_int_malloc分配内存还有释放锁
3
} else { #if USE_ARENAS /* ... or sbrk() has failed and there is still a chance to mmap() */
ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); (void)mutex_unlock(&main_arena.mutex);
if(ar_ptr) {
victim = _int_malloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
}
这里就是没有分配成但是是主分配区的也就发生上面的操作
end
#endif } }
else (void)mutex_unlock(&ar_ptr->mutex); 如果_int_malloc()函数分配内存成功,释放所使用的分配区的锁。
assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
ar_ptr == arena_for_chunk(mem2chunk(victim)));
return victim;
}
这里我们终于通过_int_malloc申请到了内存我们就会释放分配区的锁,然后函数然后的是指向chunk的member的指针我们对申请的堆块写入,打印都是通过这个指针(victim)开心
read(0,(char*)victim,0x8);