简单分析malloc和free源码实现

在编码过程中,我们往往只关心如何使用系统提供的API,比较容易忽略内在的原理。C/C++编码中,能够安全地管理内存是一项基础考察点。比如

  • malloc和free一定要配对使用,否则导致内存泄漏
  • 不要free内存两次
  • 指针非空判断
  • 不要跨模块malloc和free内存
  • 野指针问题

而今天就来说说glibc内存malloc和free的源码探究以及说明下为什么free指针时,不需要指定内存块大小

我是在这个网站找到了malloc和free的源码实现,这里给出其链接,附录给下查找过程。

https://code.woboq.org/userspace/glibc/malloc/malloc.c.html

基础定义

这里主要定义了一个allocation_header结构数组,大小为65536,结构体为记录要分配的实际内存大小和索引。

代码如下:

/* Array of known allocations, to track invalid frees.  */
enum { max_allocations = 65536 };
/*全局数组变量,最大内存分配个数为65536*/
static struct allocation_header *allocations[max_allocations];
/*记录索引*/
static size_t allocation_index;
static size_t deallocation_count;

struct  allocation_header
{
  size_t allocation_index; /*分配索引*/
  size_t allocation_size; /*分配大小*/
};

malloc实现

malloc函数内部调用了malloc_internal(), 从实现上看,malloc支持线程安全。
Alt

malloc_internal 记录了当前内存分配信息,包括实际内存分配大小和索引记录。实际内存分配会比用户申请的要多一个sizeof(allocation_header)大小.

malloc_internal 代码如下:

static void *
malloc_internal (size_t size)
{
  if (allocation_index == max_allocations)
  {
    errno = ENOMEM;
    return NULL;
  }
  
  size_t allocation_size = size + sizeof (struct allocation_header);
  if (allocation_size < size)
  {
    errno = ENOMEM;
    return NULL;
  }
  
  size_t index = allocation_index++;
  //实际内存分配
  void *result = mmap (NULL, allocation_size, PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (result == MAP_FAILED)
    return NULL;

  allocations[index] = result;
  *allocations[index] = (struct allocation_header)
    {
      .allocation_index = index,
      .allocation_size = allocation_size
    };
    
  //给用户分配的内存块开始地址,跳过头部地址
  return allocations[index] + 1;
}

free实现

我们调用完malloc之后,我们都需要调用free接口才可以,但是我们只需要传入malloc返回的地址即可,大小信息可以从头部信息获取

free源码如下:

void
free (void *ptr)
{
  if (ptr == NULL)
    return;
  lock ();
  //返回内存分配的头部信息,包含了分配的内存大小信息
  //在get_header中对ptr-1,得到实际的内存分配地址。
  struct allocation_header *header = get_header ("free", ptr);
  //完成内存释放工作
  free_internal ("free", header);
  unlock ();
}

get_header 关键代码:
在这里插入图片描述
free_internal 内部实现:
在这里插入图片描述

申请内存块实际分配模型
在这里插入图片描述

以上就是全部glibc简单的内存管理源码分析,每个版本、编译器的内存管理会有差异,但最基本的原理应该都是这样了,欢迎大家指正~~~~

附录:

给出如何查找free源码实现过程

  1. 鼠标放在free关键字上
  2. 在definitions上选择tst-interpose-aux.c文件

在这里插入图片描述
3. 跳转完成后,找到free实现源码
4. 按照相同方法可以找到全部函数实现,和IDE一样可以实现函数跳转。
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值