18.链表管理内存实现c语言自动释放内存
运行截图:

- 创建记录分配的内存地址大小和地址的结构体
struct MEM
{
void *p;
int size;
}; - 创建管理内存结构体的链表
typedef struct LinkNode
{
struct MEM *pmem;;//保存指针
struct LinkNode *pNext;//指向下一个结点
}node,*PNODE; - 设置全局变量
extern struct LinkNode *phead;
- 向链表中插入一个内存结构体,便于malloc的时候调用
PNODE addback(PNODE phead, struct MEM *pmem)
{
//开辟一个结点
PNODE pnew = (PNODE)malloc(sizeof(node));
pnew->pmem = pmem;
pnew->pNext = NULL; if (phead == NULL)
{
phead = pnew;
}
else
{
//备份首地址
PNODE ptemp = phead;
while (ptemp->pNext != NULL)
{
ptemp = ptemp->pNext;
}
ptemp->pNext = pnew;
}
return phead;
} - 修改一个指定的内存结构体,便于realloc的时候调用
PNODE change(PNODE phead, void *pfind, struct MEM *pnewmem)
{
for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
{
if (ptmp->pmem->p == pfind)
{
ptmp->pmem->p = pnewmem->p;
ptmp->pmem->size = pnewmem->size;
return phead;
}
}
return phead;
} - 删除一个内存结构体,便于free的时候调用
PNODE deletenode(PNODE phead, void *paddr)
{
//p2保存p1的前一个地址
PNODE p1, p2;
p1 = p2 = NULL;
//遍历寻找内存地址是paddr的内存结构体
p1 = phead;
while (p1 != NULL)
{
if (p1->pmem->p == paddr)
{
break;
}
else
{
p2 = p1;
p1 = p1->pNext;//备份上一个
}
} if (p1 != phead)
{
p2->pNext = p1->pNext;
free(p1);
}
else
{
phead = phead->pNext;
free(p1);
} return phead;
} - 查找指定内存的结构体,并返回找到的地址
PNODE findit(PNODE phead, void *pfind)
{
for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
{
if (ptmp->pmem->p == pfind)
{
return ptmp;
}
}
return NULL;
} - 显示内存链表的所有数据
void getinfo(PNODE phead)
{
if (phead == NULL)
{
printf("目前一共0个地址在堆上,一共消耗0个字节的内存\n");
printf("-------------------------------------------------------------------------\n\n");
return;
} int i = ;//多少个地址
int j = ;//多少个字节
for (PNODE p = phead; p != NULL; p = p->pNext)
{
i++;
j += p->pmem->size;
printf("内存地址=%p 内存大小=%d\n", p->pmem->p, p->pmem->size);
}
printf("目前一共%d个地址在堆上,一共消耗%d个字节的内存\n", i, j);
printf("-------------------------------------------------------------------------\n\n");
} - 释放链表的所有内存
PNODE deleteall(PNODE phead)
{
printf("释放所有内存\n");
printf("-------------------------------------------------------------------------\n\n");
PNODE p1 = NULL;
PNODE p2 = NULL;
p1 = phead;
while (p1 != NULL)
{
p2 = p1->pNext;
free(p1->pmem->p);
p1->pmem->p = NULL;
free(p1);
p1 = p2;
} return NULL; } - mymalloc函数,向链表中插入数据
void *mymalloc(size_t size)
{
void *p = malloc(size);
printf("分配内存 分配的地址%p 大小%d\n", p, size);
printf("-------------------------------------------------------------------------\n\n");
//创建一个结点,并且初始化,出入内存管理链表
struct MEM *pmem = (struct MEM*)malloc(sizeof(struct MEM));
pmem->p = p;
pmem->size = size;
phead = addback(phead, pmem);
return p;
} - myfree函数,在链表中删除数据
void myfree(void *p)
{
printf("\n内存地址%p释放\n", p);
printf("-------------------------------------------------------------------------\n\n");
PNODE px = findit(phead, p);
if (px == NULL)
{
return;
}
else
{
phead = deletenode(phead, p);//删除
free(p);
}
} - myrealloc在链表中修改一个数据
void *myrealloc(void *p, size_t size)
{ void *pt = realloc(p, size);
printf("内存地址%p重新分配到%p,大小%d\n",p, pt,size);
printf("-------------------------------------------------------------------------\n\n");
struct MEM mymem;
mymem.p = pt;
mymem.size = size;
phead = change(phead, p, &mymem);
return pt;
}
main函数宏定义替换 malloc,free,realloc
#define malloc mymalloc
#define free myfree
#define realloc myrealloc
完整代码:
mem.h
#include <stdio.h>
#include <stdlib.h> //记录分配的内存地址大小和地址
struct MEM
{
void *p;
int size;
}; typedef struct LinkNode
{
struct MEM *pmem;;//保存指针
struct LinkNode *pNext;//指向下一个结点
}node,*PNODE; extern struct LinkNode *phead; //向链表中插入一个数据
PNODE addback(PNODE phead, struct MEM *pmem);
//修改一个数据
PNODE change(PNODE phead, void *pfind, struct MEM *pnewmem);
//删除一个结点
PNODE deletenode(PNODE phead, void *paddr);
//显示
void showall(PNODE phead);
//查找
PNODE findit(PNODE phead,void *pfind);
//获取内存信息
void getinfo(PNODE phead);
//释放所有内存
PNODE deleteall(PNODE phead); void *mymalloc(size_t size);
void myfree(void *p);
void *myrealloc(void *p, size_t size);
mem.cpp
#include "mem.h"
struct LinkNode *phead = NULL; //插入一个数据
PNODE addback(PNODE phead, struct MEM *pmem)
{
//开辟一个结点
PNODE pnew = (PNODE)malloc(sizeof(node));
pnew->pmem = pmem;
pnew->pNext = NULL; if (phead == NULL)
{
phead = pnew;
}
else
{
//备份首地址
PNODE ptemp = phead;
while (ptemp->pNext != NULL)
{
ptemp = ptemp->pNext;
}
ptemp->pNext = pnew;
}
return phead;
} //修改一个指定的内存结构体
PNODE change(PNODE phead, void *pfind, struct MEM *pnewmem)
{
for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
{
if (ptmp->pmem->p == pfind)
{
ptmp->pmem->p = pnewmem->p;
ptmp->pmem->size = pnewmem->size;
return phead;
}
}
return phead;
} //删除一个结点
PNODE deletenode(PNODE phead, void *paddr)
{
//p2保存p1的前一个地址
PNODE p1, p2;
p1 = p2 = NULL; p1 = phead;
while (p1 != NULL)
{
if (p1->pmem->p == paddr)
{
break;
}
else
{
p2 = p1;
p1 = p1->pNext;//备份上一个
}
} if (p1 != phead)
{
p2->pNext = p1->pNext;
free(p1);
}
else
{
phead = phead->pNext;
free(p1);
} return phead;
} //显示所有数据
void showall(PNODE phead)
{
if (phead == NULL)
{
printf("-------------------------------------------------------------------------\n\n");
return;
}
else
{
printf("内存地址=%p 内存大小=%d\n", phead->pmem->p, phead->pmem->size);
showall(phead->pNext);
}
} //查找
PNODE findit(PNODE phead, void *pfind)
{
for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
{
if (ptmp->pmem->p == pfind)
{
return ptmp;
}
}
return NULL;
} //获取信息
void getinfo(PNODE phead)
{
if (phead == NULL)
{
printf("目前一共0个地址在堆上,一共消耗0个字节的内存\n");
printf("-------------------------------------------------------------------------\n\n");
return;
} int i = ;//多少个地址
int j = ;//多少个字节
for (PNODE p = phead; p != NULL; p = p->pNext)
{
i++;
j += p->pmem->size;
printf("内存地址=%p 内存大小=%d\n", p->pmem->p, p->pmem->size);
}
printf("目前一共%d个地址在堆上,一共消耗%d个字节的内存\n", i, j);
printf("-------------------------------------------------------------------------\n\n");
} //释放所有内存
PNODE deleteall(PNODE phead)
{
printf("释放所有内存\n");
printf("-------------------------------------------------------------------------\n\n");
PNODE p1 = NULL;
PNODE p2 = NULL;
p1 = phead;
while (p1 != NULL)
{
p2 = p1->pNext;
free(p1->pmem->p);
p1->pmem->p = NULL;
free(p1);
p1 = p2;
} return NULL; } void *mymalloc(size_t size)
{
void *p = malloc(size);
printf("分配内存 分配的地址%p 大小%d\n", p, size);
printf("-------------------------------------------------------------------------\n\n");
//创建一个结点,并且初始化,出入内存管理链表
struct MEM *pmem = (struct MEM*)malloc(sizeof(struct MEM));
pmem->p = p;
pmem->size = size;
phead = addback(phead, pmem);
return p;
} void myfree(void *p)
{
printf("\n内存地址%p释放\n", p);
printf("-------------------------------------------------------------------------\n\n");
PNODE px = findit(phead, p);
if (px == NULL)
{
return;
}
else
{
phead = deletenode(phead, p);//删除
free(p);
}
} void *myrealloc(void *p, size_t size)
{ void *pt = realloc(p, size);
printf("内存地址%p重新分配到%p,大小%d\n",p, pt,size);
printf("-------------------------------------------------------------------------\n\n");
struct MEM mymem;
mymem.p = pt;
mymem.size = size;
phead = change(phead, p, &mymem);
return pt;
}
main.c
#include "mem.h" #define malloc mymalloc
#define free myfree
#define realloc myrealloc void main()
{
void *p1 = malloc(**);
void *p2 = malloc( * * );
void *p3 = malloc( * * );
getinfo(phead);
realloc(p1, );
getinfo(phead);
free(p3);
getinfo(phead);
phead = deleteall(phead);
getinfo(phead);
system("pause");
}
18.链表管理内存实现c语言自动释放内存的更多相关文章
- C++函数中,两个自动释放内存的动态内存申请类
最近做一个事情,实现一个流程交互,其中主交互流程函数中,涉及较多的内存申请, 而健康的函数,都是在函数退出前将手动申请不再需要的内存释放掉, 使用很多方法,都避免不了较多的出错分支时,一堆的if fr ...
- iOS内存管理系列之二:自动释放与便捷方法
有时候一个所有者创建一个对象后,会立刻将该对象的指针传递给其它所有者.这时,这个创建者不希望再拥有这个对象,但如果立刻给它发送一个release消息会导致这个对象被立刻释放掉——这样其它所有者还没有来 ...
- ARC 没有自动释放内存
http://www.cnblogs.com/qingche/p/4569833.html 定位了好几天,才发现是打印日志没有即时释放内存,使用intrustment
- Linux 查看内存(free)、释放内存(基本操作)
原文链接:http://blog.51cto.com/11495268/2384147 1.简介 1.1 介绍 很多时候,服务器 负载 很高(执行操作 很慢),很多 原因 造成 这种 现象(内存不足 ...
- C语言中的内存相关问题
内存是用来存储数据与程序的,对我们写程序来说非常重要.所以内存对程序来说几乎是本质需求.越简单的程序需要越少的内存,而越庞大越复杂的程序需要更多的内存. 注意:在嵌入式系统中有ROM和RAM两类内存, ...
- How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题
个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...
- C语言中动态内存分配的本质是什么?
摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...
- [c语言]c语言中的内存分配[转]
在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...
- JavaScript 工作原理之三-内存管理及如何处理 4 类常见的内存泄漏问题(译)
原文请查阅这里,本文有进行删减,文后增了些经验总结. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第三章. 我们将会讨论日常使用中另一个被开发者越来越忽略的 ...
随机推荐
- Python dataframe中如何使y列按x列进行统计?
如图:busy=0 or 1,求出busy=1时los的平均,同样对busy=0时也求出los的平均 Python dataframe中如何使y列按x列进行统计? >> python这个答 ...
- JavaScript总结(4)
如何绑定事件 程序员可以编写代码,要求页面在发生了某些事件时调用相应的JavaScript语句或函数,这被称为事件的绑定.事件的绑定有3种方式.1)在HTML标记中直接声明,这是最常见的一种做法.语法 ...
- windows, fast-rcnn CPU版本的安装配置
一:安装准备 1:caffe的安装配置,本人用的是happynear大神的caffe版本,具体链接https://github.com/happynear/caffe-windows,编译时需要用到p ...
- js控制分页打印、打印分页示例
1 打印分页 需要添加一段代码 <div style="page-break-before:always;"><br /></div> 2 & ...
- vmware fusion8 序列号
- Audio / Video Playback
For Developers > Design Documents > Audio / Video Playback Interested in helping out? Ch ...
- [POI2008]PLA-Postering(单调栈)
题意 N个矩形,排成一排. 现在希望用尽量少的矩形海报Cover住它们. (n<=250000,wi,di<=109) 题解 这种一堆矩形,又不像数据结构的题,一般都是单调栈. 考虑一个贪 ...
- BZOJ5017 炸弹(线段树优化建图+Tarjan+拓扑)
Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...
- MySql系列之初识
数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件都运 ...
- What is x86 Conforming Code Segment?
SRC=Microprocessor Based Systems SRC=Computer Architecture: A Quantitative Approach