dlmalloc(四)

这篇博客探讨了dlmalloc库中释放内存的过程,详细介绍了free()函数的执行步骤。当调用free(ptr)释放内存时,dlmalloc会将内存块标记为空闲,并根据内存大小决定是否直接通过munmap()释放或尝试合并相邻空闲块。如果top chunk超过2MB,还会进行收缩操作。文章还展示了内存大于256KB时释放的具体代码和top chunk收缩的实现。
摘要由CSDN通过智能技术生成

这篇文章我们来讲讲释放内存的过程,也就是free()的代码流程。对于应用程序来说释放内存很简单,直接调用free(ptr)就可以了,参数是要释放的内存块指针。那么,释放内存时dlmalloc做了哪些工作呢?

// 这是释放内存的函数,调用free()后执行到这里.
// 参数mem: 这是将要释放内存的指针
void dlfree(void* mem) {
  /*
     Consolidate freed chunks with preceeding or succeeding bordering
     free chunks, if they exist, and then place in a bin.  Intermixed
     with special cases for top, dv, mmapped chunks, and usage errors.
  */
  // 如果是空指针,那么就不需要处理了.
  if (mem != 0) {
    mchunkptr p  = mem2chunk(mem);	// 首先找到内存块的起始地址  p = mem - 8.
#if FOOTERS	// 将这个宏看作是0就可以了
    mstate fm = get_mstate_for(p);
    if (!ok_magic(fm)) {
      USAGE_ERROR_ACTION(fm, p);
      return;
    }
#else /* FOOTERS */
#define fm gm	// 全局变量_gm_的地址
#endif /* FOOTERS */
    if (!PREACTION(fm)) {	// 先加锁
      check_inuse_chunk(fm, p);	// 检查这个chunk是否在使用中,这是一个检查函数.
      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
        size_t psize = chunksize(p);	// 计算这个内存块的大小.
        mchunkptr next = chunk_plus_offset(p, psize);	// 从这里开始是下一个内存块了.

        if (!pinuse(p)) { // 如果前面一个内存块是空闲的,那么这个内存块释放后就可以跟前面一个内存块合并了.
          size_t prevsize = p->prev_foot;	// 前面一个内存块的大小

          if ((prevsize & IS_MMAPPED_BIT) != 0) { // 如果是通过mmap方式创建的内存块
            prevsize &= ~IS_MMAPPED_BIT;
            psize += prevsize + MMAP_FOOT_PAD;
            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
              fm->footprint -= psize;
            goto postaction;
          }
          else { // 不是通过mmap方式创建的.
            mchunkptr prev = chunk_minus_offset(p, prevsize);	// 取出前面一个chunk的结构.
            psize += prevsize;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值