malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存,且分配的大小就是程序要求的大小。
malloc底层实现
首先讲一下malloc这个函数
void* malloc(size_t size);
malloc是c里面的函数,调用时候需要显示的指定分配空间的大小,分配成功会返回void *
的指针,需要自己进行强制转换,不安全,失败返回NULL
相关函数
int brk(const void *addr)
函数是为了扩展heap的上界brk的。0成功 -1失败
void* sbrk(intprt_t incr)
需要申请内存的大小并且返回heap新上届brk的地址
void *mmap(void *addr, size\_t length, int prot, int flags, int fd, off\_t offset);
函数是将磁盘文件映射到内存中,直接修改内存那么就可以操作DISK
注意这里分配的只是虚拟内存,只有当使用的使用产生缺页中断的时候由操作系统进行分配并建立映射
malloc分配规则
- 当申请小于
128k
内存的时候malloc会调用brk()
来进行内存的分配 - 当申请大于
128k
的内存的时候malloc会调用mmap()
来进行内存的分配
这个原因是因为,brk()分配的内存只有当高地址的内存被释放了低地址的才能被释放。而mmap申请的内存是可以单独释放的
这时候还是会引发问题
就是当我们频发的调用malloc的时候,会调用上面函数中的一个,这些就会产生系统开销,同时也会产生大量的内存碎片。这时候就需要一个内存池帮助我们管理内存,减少内存碎片的产生
内存池
内存池其实就是小申请一大块内存作为heap区,然后把大块内存分成一块块小内存,当用户申请内存的时候,就直接分配一块合适的空闲块。采用隐式链表将多有的空闲内存块连接起来,每一个内存块里面都是连续的内存
这里维持着16条链表,每条链表(双向链表)都维持不同的固定大小的内存块
到此这篇关于c++中的malloc底层实现代码的文章就介绍到这了,更多相关c++ malloc底层内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!