malloc,free的简单实现
来源:互联网 发布:excel03显示重复数据 编辑:程序博客网 时间:2024/05/22 05:01
首先简单说一下标准库中malloc实现原理:
标准库内部通过一个双向链表,管理在堆中动态分配的内存。
malloc函数分配内存时会附加若干(通常是12个)字节,存放控制信息。
该信息一旦被意外损坏,可能在后续操作中引发异常。
malloc函数分配内存时会附加若干(通常是12个)字节,存放控制信息。
该信息一旦被意外损坏,可能在后续操作中引发异常。
mmap/munmap 底层不维护任何东西,只是返回一个首地址,所分配内存位于堆中。
brk/sbrk 底层维护一个指针,记录所分配的内存结尾,所分配内存位于堆中,底层调用mmap/munmap。
malloc 底层维护一个双向链表和必要的控制信息,不可越界访问,所分配内存位于堆中,底层调用brk/sbrk。
每个进程都有4G的虚拟内存空间,虚拟内存地址只是一个数字,并没有和实际的物理内存相关联。
brk/sbrk 底层维护一个指针,记录所分配的内存结尾,所分配内存位于堆中,底层调用mmap/munmap。
malloc 底层维护一个双向链表和必要的控制信息,不可越界访问,所分配内存位于堆中,底层调用brk/sbrk。
每个进程都有4G的虚拟内存空间,虚拟内存地址只是一个数字,并没有和实际的物理内存相关联。
所谓内存分配与释放,其本质就是建立或取消虚拟内存和物理内存间的映射关系。
几个用到的函数:
void* sbrk (
intptr_t increment // 内存增量(以字节为单位)
);
intptr_t increment // 内存增量(以字节为单位)
);
返回上次调用brk/sbrk后的末尾地址,失败返回-1。
increment取值:
0 - 获取末尾地址。
>0 - 增加内存空间。
<0 - 释放内存空间。
内部维护一个指针,指向当前堆内存最后一个字节的下一个位置。
sbrk函数根据增量参数调整该指针的位置,同时返回该指针原来的位置。
若发现页耗尽或空闲,则自动追加或取消页映射。
0 - 获取末尾地址。
>0 - 增加内存空间。
<0 - 释放内存空间。
内部维护一个指针,指向当前堆内存最后一个字节的下一个位置。
sbrk函数根据增量参数调整该指针的位置,同时返回该指针原来的位置。
若发现页耗尽或空闲,则自动追加或取消页映射。
int brk (
void* end_data_segment // 内存块末尾地址
);
成功返回0,失败返回-1。
内部维护一个指针,指向当前堆内存最后一个字节的下一个位置。
brk函数根据指针参数设置该指针的位置。
若发现页耗尽或空闲,则自动追加或取消页映射。
);
成功返回0,失败返回-1。
内部维护一个指针,指向当前堆内存最后一个字节的下一个位置。
brk函数根据指针参数设置该指针的位置。
若发现页耗尽或空闲,则自动追加或取消页映射。
sbrk/brk底层维护一个指针位置,以页(4K)为单位分配和释放虚拟内存。
简便起见,可用sbrk分配内存,用brk释放内存。
简便起见,可用sbrk分配内存,用brk释放内存。
#include <stdio.h>#include <unistd.h>#include <stdbool.h>typedef struct mem_control_block //内存控制块{bool free; //自由标志struct mem_control_block* prev; //前向指针size_t size; //块大小}MCB;MCB* g_top; //内存栈顶指针// +----------------------+ g_top// v | |// +------+------------+--|---+------------+------+------------+// | prev | | prev | | prev | |// | free | | free | | free | |// | size | | size | | size | |// +------+------------+------+------------+------+------------+// MCB |<-- size -->|void* my_malloc(size_t size){MCB* mcb;for(mcb = g_top; mcb; mcb = mcb->prev)if(mcb->free && mcb->size >= size)//寻找可用空块break;if(!mcb) //如果没有可用空块{mcb = sbrk(sizeof(MCB) + size); //增量分配size大小内存if(mcb == (void*)-1) //如果分配失败,打印错误信息{perror("sbrk");return NULL;}mcb->prev = g_top; //调整前向指针mcb->size = size; //大小g_top = mcb; //调整栈顶指针}mcb->free = false; //无论用原来空块还是新分配的块,都标记为不可用return mcb + 1; //返回实际分配的内存起始地址}void my_free(void* ptr){if(!ptr)return;MCB* mcb = (MCB*)ptr - 1; //取控制块起始地址,//注意:ptr为实际可用内存起始地址mcb->free = true; //块标记为可用//在栈中查找连续内存块for(mcb = g_top; mcb->prev; mcb = mcb->prev)if(!mcb->free)break;//释放整个栈所有内存块if(mcb->free){g_top = mcb->prev;brk(mcb); //修改内存块末尾地址}else //释放连续的标记为true的内存块{g_top = mcb;brk((void*)mcb + sizeof(MCB) + mcb->size);}}//测试int main(void){int* pa[10];size_t size = sizeof(pa) / sizeof(pa[0]), i, j;for(i = 0; i < size; ++i){if(!(pa[i] = (int*)my_malloc((i+1) * sizeof(int)))){perror("my_malloc");return -1;}for(j = 0; j <= i; ++j)pa[i][j] = j;}for(i = 0; i < size; ++i){for(j = 0; j <= i; ++j)printf("%d ", pa[i][j]);printf("\n");}for(;;){my_free(pa[--i]);if(! i)break;}return 0;}
0 0
- malloc,free的简单实现
- 简单的malloc,free实现函数
- malloc calloc realloc free的简单实现
- malloc()/free()的实现
- malloc()/free()的实现
- malloc/free的实现
- malloc()/free()的实现
- malloc()/free()的实现
- unix的malloc/free函数的简单实现及思考
- 最简单的malloc free函数实现(用于arms3c2440)
- malloc/free函数的简单实现及思考
- malloc/free函数的简单实现及思考
- malloc/free函数的简单实现及思考
- malloc和free的实现
- malloc和free实现的原理
- avr-libc malloc/free的实现
- 改进的malloc/free实现源码
- malloc和free实现的原理
- x4412开发板&ibox卡片电脑项目实战14-linux驱动的编写步骤
- 用Emacs muse制作幻灯片
- 高性能网络编程(一)----accept建立连接
- 代码流程分析
- 在N9使用TabGround进行页面导航(02)
- malloc,free的简单实现
- Mina、Netty、Twisted一起学(九):异步IO和回调函数
- for 和 foreach 的区别
- 通过网页获取路由器外网IP地址
- webView 报错
- 【Algorithm】关于n!被整除的问题【算法实现】
- linux创建守护进程
- 基于TCP协议的视频传输
- Android Graphics Architecture翻译(上)