C语言: 基于链表的内存管理Dome

基于单链表(也可以用数组)实现的程序内存管理,对内存的安全释放和开辟空间大小以及地址的管理和数据展示。

头文件:mymemory.h

#pragma once
#include<stdio.h>
#include<stdlib.h>

/* 
	记录开辟内存
*/
void* mymalloc(size_t size);

/*
	记录释放内存
*/
void myfree(void *vPtr);

/*
	记录改变内存
*/
void *myrealloc(void* vPtr, size_t size);


/*记录内存空间大小以及地址*/
struct MEMORY
{
	void* vPtr;
	size_t size;
};

/*内存链表结构体*/
typedef struct LinkNode_MEM
{
	struct MEMORY* vPtr_Mem;//保存内存信息
	struct LinkNode_MEM* vPtr_Next;//指向下一个节点
}LNMEM ,*P_LNMEM;

struct LinkNode_MEM* LNM; //声明全局链表变量

/********************************************
  插入数据
  -------------------------------------------
  参数   |  P_LNMEM head            :  头节点
		    struct MEMORY* vPtr_Mem :  新节点 
  -------------------------------------------
  返回   |  指针  /  NULL 

*********************************************/
P_LNMEM add_back(P_LNMEM head, struct MEMORY* vPtr_Mem);

/********************************************
  修改数据
  -------------------------------------------
  参数   |  P_LNMEM head            : 头节点
			struct MEMORY* vPtr_Mem : 新节点
			void* vPtr_old          : 旧节点
  -------------------------------------------
  返回   |  指针  /  NULL
*********************************************/
P_LNMEM reapportion(P_LNMEM head, void* vPtr_old, struct MEMORY* vPtr_MemNew);

/********************************************
  释放指定地址内存
  ------------------------------------------
  参数    |  P_LNMEM head     :头节点
			void* vPtr_addr  :释放的节点指针
  ------------------------------------------
  返回    |  指针

*********************************************/
P_LNMEM FMR_Memory_Cleaner(P_LNMEM head, void* vPtr_addr);

/********************************************
  查看所有数据
  ------------------------------------------
  参数          |  P_LNMEM head:头节点
  ------------------------------------------
  返回          |  无 	
*********************************************/
void view_all_data(P_LNMEM head);

/********************************************
  查找节点
  ------------------------------------------
  参数   |  P_LNMEM head    : 头节点
		   void* vPtr       : 查找的节点地址
  ------------------------------------------
  返回   |  指针 / NULL
*********************************************/
P_LNMEM find_node(P_LNMEM head, void* vPtr);

/********************************************
  获取内存信息
  ------------------------------------------
  参数          |  P_LNMEM head:头节点
  ------------------------------------------
  返回          |  无
*********************************************/
void get_memInfo(P_LNMEM head);

/********************************************
  释放全部内存空间
  ------------------------------------------
  参数          |  P_LNMEM head:头节点
  ------------------------------------------
  返回          |  无
*********************************************/
P_LNMEM free_memAll(P_LNMEM head);

源文件:mymemory.c


#include"mymemory.h"

/*定义全局链表变量*/
struct LinkNode_MEM* LNM = NULL;

/*
	记录开辟内存
*/
void* mymalloc(size_t size)
{
	void* vPtr = (void*)malloc(size);
	if (vPtr != NULL)
	{
		//printf("分配内存 :地址 【%p】; 大小 【%d】\n", vPtr, size);
		struct MEMORY* vPtr_Mem = (struct MEMORY*)malloc(sizeof(struct MEMORY));
		if (vPtr_Mem != NULL)
		{
			vPtr_Mem->vPtr = vPtr;
			vPtr_Mem->size = size;

			LNM = add_back(LNM, vPtr_Mem);
		}
	}
	return vPtr;
}

/*
	记录释放内存
*/
void myfree(void* vPtr)
{
	P_LNMEM p = find_node(LNM, vPtr);
	if (p == NULL)
	{
		return;
	}
	else
	{
		FMR_Memory_Cleaner(LNM, vPtr);
		free(vPtr);
	}
	
	//printf("释放内存 :地址 【%p】 \n", vPtr);
}

/*
	记录改变内存
*/
void* myrealloc(void* vPtr, size_t size)
{
	void* vPtr_New = (void*)realloc(vPtr, size);
	if (vPtr_New != NULL)
	{
		//printf("内存地址 【%p】, 重新分配 ( 地址【%p】, 大小 【%d】)\n", vPtr, vPtr_New, size);
		struct MEMORY mem;
		mem.vPtr = vPtr_New;
		mem.size = size;
		LNM = reapportion(LNM, vPtr, &mem);
	}
	return vPtr_New;
}



/********************************************
  查看所有数据
  ------------------------------------------
  参数          |  P_LNMEM head:头节点
  ------------------------------------------
  返回          |  无
*********************************************/
void view_all_data(P_LNMEM head)
{
	if (head == NULL)
	{
		return;
	}
	else
	{
		printf("memory address:【%p】; size: 【%d】\n", head->vPtr_Mem->vPtr, head->vPtr_Mem->size);
		view_all_data(head->vPtr_Next);
	}
}

/********************************************
  插入数据
  -------------------------------------------
  参数   |  P_LNMEM head            :  头节点
			struct MEMORY* vPtr_Mem :  新节点
  -------------------------------------------
  返回   |  指针  /  NULL

*********************************************/
P_LNMEM add_back(P_LNMEM head, struct MEMORY* vPtr_Mem)
{
	P_LNMEM newMEM = malloc(sizeof(LNMEM));//开辟新节点
	if (newMEM != NULL)
	{
		newMEM->vPtr_Mem = vPtr_Mem;
		newMEM->vPtr_Next = NULL;

		if (head == NULL)
		{
			head = newMEM;
		}
		else
		{
			P_LNMEM temp = head;
			while (temp->vPtr_Next!=NULL)
			{
				temp = temp->vPtr_Next;
			}
			temp->vPtr_Next = newMEM;
		}
	}
	return head;
}

/********************************************
  修改数据
  -------------------------------------------
  参数   |  P_LNMEM head            :头节点
			struct MEMORY* vPtr_Mem : 新节点
			void* vPtr_old          : 旧节点
  -------------------------------------------
  返回   |  指针  /  NULL
*********************************************/
P_LNMEM reapportion(P_LNMEM head, void* vPtr_old, struct MEMORY* vPtr_MemNew)
{
	for (P_LNMEM ptr = head; ptr != NULL; ptr = ptr->vPtr_Next)
	{
		if (ptr->vPtr_Mem->vPtr == vPtr_old)
		{
			ptr->vPtr_Mem->vPtr = vPtr_MemNew->vPtr;
			ptr->vPtr_Mem->size = vPtr_MemNew->size;
			return head;
		}
	}
	return head;
}

/********************************************
  查找节点
  ------------------------------------------
  参数   |  P_LNMEM head    : 头节点
		   void* vPtr       : 查找的节点地址
  ------------------------------------------
  返回   |  指针 / NULL
*********************************************/
P_LNMEM find_node(P_LNMEM head, void* vPtr_addr)
{
	for (P_LNMEM ptr = head; ptr != NULL; ptr = ptr->vPtr_Next)
	{
		if (ptr->vPtr_Mem->vPtr == vPtr_addr)
		{
			return ptr;
		}
	}
	return NULL;
}

/********************************************
  释放指定地址内存
  ------------------------------------------
  参数    |  P_LNMEM head     :头节点
			void* vPtr_addr  :释放的节点指针
  ------------------------------------------
  返回    |  指针

*********************************************/
P_LNMEM FMR_Memory_Cleaner(P_LNMEM head, void* vPtr_addr)
{
	if (head == NULL||head->vPtr_Next==NULL)
	{
		return head;
	}
	else
	{
		P_LNMEM p1, p2;
		p1 = p2 = NULL;
		p1 = head;
		while (p1 != NULL)
		{
			if (p1->vPtr_Mem->vPtr == vPtr_addr)
			{
				break;
			}
			else
			{
				p2 = p1;
				p1 = p1->vPtr_Next;
			}
		}
		if (p1 != head)
		{
			p2->vPtr_Next = p1->vPtr_Next;
			free(p1);
		}
		else
		{
			head = head->vPtr_Next;
			free(p1);
		}
	}

	

	return head;
}

/********************************************
  获取内存信息
  ------------------------------------------
  参数          |  P_LNMEM head:头节点
  ------------------------------------------
  返回          |  无
*********************************************/
void get_memInfo(P_LNMEM head)
{
	int addCount = 0; //地址数量
	int byteCount = 0;//内存字节数量
	printf("\n**************************************\n");
	printf("********** 程序使用内存信息 **********\n");
	printf("**************************************\n\n");
	if (head != NULL)
	{
		for (P_LNMEM ptr = head; ptr != NULL; ptr = ptr->vPtr_Next)
		{
			addCount++;
			byteCount += ptr->vPtr_Mem->size;
			printf("memory address:【%p】; size: 【%d】\n", ptr->vPtr_Mem->vPtr, ptr->vPtr_Mem->size);
		}
	}
	printf("\n内存占用地址个数:【%d】; 内存占用字节大小:【%d】 \n", addCount, byteCount);
	
	printf("\n**************************************\n\n");
}

/********************************************
  释放全部内存空间
  ------------------------------------------
  参数          |  P_LNMEM head:头节点
  ------------------------------------------
  返回          |  无
*********************************************/
P_LNMEM free_memAll(P_LNMEM head)
{
	if (head == NULL)
	{
		return NULL;
	}
	else
	{
		P_LNMEM p1 = NULL, p2 = NULL;
		p1 = head;
		while (p1->vPtr_Next!=NULL)
		{
			p2 = p1->vPtr_Next;
			p1->vPtr_Next = p2->vPtr_Next;
			free(p2->vPtr_Mem->vPtr);
			free(p2);

			//p1 = p1->vPtr_Next;
		}
		free(head->vPtr_Mem->vPtr);
		free(head);
		return NULL;
	}
}

调用示例:


#include"mymemory.h"

#define malloc mymalloc
#define free myfree
#define realloc myrealloc


void main()
{
	size_t size = 1024*1024*1024;
	void* vPtr1 = malloc(size);
	void* vPtr2 = malloc(size);
	void* vPtr3 = malloc(size);
	void* vPtr4 = malloc(size);
	void* vPtr5 = malloc(size);
	printf("\n\n");
	view_all_data(LNM);
	printf("\n\n");
	void* p1 = realloc(vPtr1, size*2);
	void* p2 = realloc(vPtr2, size * 2);
	view_all_data(LNM);
	printf("\n\n");
	
	free(vPtr3);
	free(vPtr4);
	free(0x2222);//随便释放
	view_all_data(LNM);

	get_memInfo(LNM);

	LNM=free_memAll(LNM);

	get_memInfo(LNM);
	system("pause");
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值