malloc,free的简单实现

首先简单说一下标准库中malloc实现原理:

标准库内部通过一个双向链表,管理在堆中动态分配的内存。

malloc函数分配内存时会附加若干(通常是12个)字节,存放控制信息。

该信息一旦被意外损坏,可能在后续操作中引发异常。

mmap/munmap   底层不维护任何东西,只是返回一个首地址,所分配内存位于堆中

brk/sbrk   底层维护一个指针,记录所分配的内存结尾,所分配内存位于堆中,底层调用mmap/munmap。

malloc   底层维护一个双向链表和必要的控制信息,不可越界访问,所分配内存位于堆中,底层调用brk/sbrk。

每个进程都有4G的虚拟内存空间,虚拟内存地址只是一个数字,并没有和实际的物理内存相关联。

所谓内存分配与释放,其本质就是建立或取消虚拟内存和物理内存间的映射关系

几个用到的函数:

void*
sbrk
(

intptr_t  increment // 内存增量(以字节为单位)

);

返回上次调用brk/sbrk后的末尾地址,失败返回-1。

increment取值:

0 - 获取末尾地址。

>0 - 增加内存空间。

<0 - 释放内存空间。

内部维护一个指针,指向当前堆内存最后一个字节的下一个位置。

sbrk函数根据增量参数调整该指针的位置,同时返回该指针原来的位置。

若发现页耗尽或空闲,则自动追加或取消页映射。

int
brk
(

void* end_data_segment // 内存块末尾地址

);

成功返回0,失败返回-1。

内部维护一个指针,指向当前堆内存最后一个字节的下一个位置。

brk函数根据指针参数设置该指针的位置。

若发现页耗尽或空闲,则自动追加或取消页映射。

sbrk/brk底层维护一个指针位置,以页(4K)为单位分配和释放虚拟内存。

简便起见,可用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;
}

时间: 2024-08-02 21:43:32

malloc,free的简单实现的相关文章

如何实现一个malloc

任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解. 这篇文章通过实现一个简单的malloc来描述malloc背后的机制.当然与现有C的标准库

malloc实现

任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放 掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是 C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解. 这篇文章通过实现一个简单的malloc来描述malloc背后的机制.当然与现有C的标

malloc的原理

任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一 段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统 所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解. 这篇文章通过实现一个简单的malloc来描述malloc背后的机制.当然与现有C的标

如何实现一个malloc(转)

本文转自博文如何实现一个malloc.就如作者本人所说,该博文大量参考了A malloc Tutorial,所以对照着阅读这两篇文章更能加深理解. 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,

[转] malloc基本实现

任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解. 这篇文章通过实现一个简单的malloc来描述malloc背后的机制.当然与现有C的标准库

malloc/free和new/delete

一. 执行内容: malloc / free: malloc 函数的参数接收所需分配的内存字节数,如果内存满足请求量,将返回指向被分配内存起始地址的指针: free 释放指针所指向的内存,其中指针必须指向所释放内存空间的首地址: new / delete: new 分为两步:1).通过operator new 分配内存      2).为被分配的内存调用一个或多个构造函数构建对象: delete 也分两步: 1).为将被释放的内存调用一个或多个析构函数      2).通过operator de

@清晰掉 malloc是如何分配内存的?

任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解. 这篇文章通过实现一个简单的malloc来描述malloc背后的机制.当然与现有C的标准库

malloc基本实现

转自:http://www.cnblogs.com/wangshide/p/3932539.html 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以

【转载】ogre内存管理

原文:ogre内存管理 OGRE内存分配策略相关文件及简述 OGRE提供了自己的内存分配策略,甚至为STL容器提供了新的分配策略,相关文件及简述如下: OgreMemoryAllocatedObject.h  OgreMemoryAllocatedObject.cpp // 所有使用Ogre内存分配器的类的父类 OgreMemoryAllocatorConfig.h // 配置内存分配相关规则 OgreMemoryNedAlloc.h  OgreMemoryNedAlloc.cpp // 使用n