18.链表管理内存实现c语言自动释放内存

运行截图:

 

  • 创建记录分配的内存地址大小和地址的结构体
    1 struct MEM
    2 {
    3     void *p;
    4     int size;
    5 };

     

  • 创建管理内存结构体的链表
    1 typedef struct LinkNode
    2 {
    3     struct MEM *pmem;;//保存指针
    4     struct LinkNode *pNext;//指向下一个结点
    5 }node,*PNODE;

     

  • 设置全局变量
    1 extern struct LinkNode *phead;

     

  • 向链表中插入一个内存结构体,便于malloc的时候调用
     1 PNODE addback(PNODE phead, struct MEM *pmem)
     2 {
     3     //开辟一个结点
     4     PNODE pnew = (PNODE)malloc(sizeof(node));
     5     pnew->pmem = pmem;
     6     pnew->pNext = NULL;
     7 
     8     if (phead == NULL)
     9     {
    10         phead = pnew;
    11     }
    12     else
    13     {
    14         //备份首地址
    15         PNODE ptemp = phead;
    16         while (ptemp->pNext != NULL)
    17         {
    18             ptemp = ptemp->pNext;
    19         }
    20         ptemp->pNext = pnew;
    21     }
    22     return phead;
    23 }

     

  • 修改一个指定的内存结构体,便于realloc的时候调用
     1 PNODE change(PNODE phead, void *pfind, struct MEM *pnewmem)
     2 {
     3     for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
     4     {
     5         if (ptmp->pmem->p == pfind)
     6         {
     7             ptmp->pmem->p = pnewmem->p;
     8             ptmp->pmem->size = pnewmem->size;
     9             return phead;
    10         }
    11     }
    12     return phead;
    13 }

     

  • 删除一个内存结构体,便于free的时候调用
     1 PNODE deletenode(PNODE phead, void *paddr)
     2 {
     3     //p2保存p1的前一个地址
     4     PNODE p1, p2;
     5     p1 = p2 = NULL;
     6     //遍历寻找内存地址是paddr的内存结构体
     7     p1 = phead;
     8     while (p1 != NULL)
     9     {
    10         if (p1->pmem->p == paddr)
    11         {
    12             break;
    13         }
    14         else
    15         {
    16             p2 = p1;
    17             p1 = p1->pNext;//备份上一个
    18         }
    19     }
    20 
    21     if (p1 != phead)
    22     {
    23         p2->pNext = p1->pNext;
    24         free(p1);
    25     }
    26     else
    27     {
    28         phead = phead->pNext;
    29         free(p1);
    30     }
    31 
    32     return phead;
    33 }

     

  • 查找指定内存的结构体,并返回找到的地址
     1 PNODE findit(PNODE phead, void *pfind)
     2 {
     3     for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
     4     {
     5         if (ptmp->pmem->p == pfind)
     6         {
     7             return ptmp;
     8         }
     9     }
    10     return NULL;
    11 }

     

  • 显示内存链表的所有数据
     1 void getinfo(PNODE phead)
     2 {
     3     if (phead == NULL)
     4     {
     5         printf("目前一共0个地址在堆上,一共消耗0个字节的内存\n");
     6         printf("-------------------------------------------------------------------------\n\n");
     7         return;
     8     }
     9 
    10     int i = 0;//多少个地址
    11     int j = 0;//多少个字节
    12     for (PNODE p = phead; p != NULL; p = p->pNext)
    13     {
    14         i++;
    15         j += p->pmem->size;
    16         printf("内存地址=%p     内存大小=%d\n", p->pmem->p, p->pmem->size);
    17     }
    18     printf("目前一共%d个地址在堆上,一共消耗%d个字节的内存\n", i, j);
    19     printf("-------------------------------------------------------------------------\n\n");
    20 }

     

  • 释放链表的所有内存
     1 PNODE deleteall(PNODE phead)
     2 {
     3     printf("释放所有内存\n");
     4     printf("-------------------------------------------------------------------------\n\n");
     5     PNODE p1 = NULL;
     6     PNODE p2 = NULL;
     7     p1 = phead;
     8     while (p1 != NULL)
     9     {
    10         p2 = p1->pNext;
    11         free(p1->pmem->p);
    12         p1->pmem->p = NULL;
    13         free(p1);
    14         p1 = p2;
    15     }
    16 
    17     return NULL;
    18     
    19 }

     

  • mymalloc函数,向链表中插入数据
     1 void *mymalloc(size_t size)
     2 {
     3     void *p = malloc(size);
     4     printf("分配内存        分配的地址%p    大小%d\n", p, size);
     5     printf("-------------------------------------------------------------------------\n\n");
     6     //创建一个结点,并且初始化,出入内存管理链表
     7     struct MEM *pmem = (struct MEM*)malloc(sizeof(struct MEM));
     8     pmem->p = p;
     9     pmem->size = size;
    10     phead = addback(phead, pmem);
    11     return p;
    12 }

     

  • myfree函数,在链表中删除数据
     1 void myfree(void *p)
     2 {
     3     printf("\n内存地址%p释放\n", p);
     4     printf("-------------------------------------------------------------------------\n\n");
     5     PNODE px = findit(phead, p);
     6     if (px == NULL)
     7     {
     8         return;
     9     }
    10     else
    11     {
    12         phead = deletenode(phead, p);//删除
    13         free(p);
    14     }
    15 }

     

  • myrealloc在链表中修改一个数据
     1 void *myrealloc(void *p, size_t size)
     2 {
     3     
     4     void *pt = realloc(p, size);
     5     printf("内存地址%p重新分配到%p,大小%d\n",p, pt,size);
     6     printf("-------------------------------------------------------------------------\n\n");
     7     struct MEM mymem;
     8     mymem.p = pt;
     9     mymem.size = size;
    10     phead = change(phead, p, &mymem);
    11     return pt;
    12 }

     

main函数宏定义替换 malloc,free,realloc

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

完整代码:

mem.h

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 //记录分配的内存地址大小和地址
 5 struct MEM
 6 {
 7     void *p;
 8     int size;
 9 };
10 
11 typedef struct LinkNode
12 {
13     struct MEM *pmem;;//保存指针
14     struct LinkNode *pNext;//指向下一个结点
15 }node,*PNODE;
16 
17 extern struct LinkNode *phead;
18 
19 //向链表中插入一个数据
20 PNODE addback(PNODE phead, struct MEM *pmem);
21 //修改一个数据
22 PNODE change(PNODE phead, void *pfind, struct MEM *pnewmem);
23 //删除一个结点
24 PNODE deletenode(PNODE phead, void *paddr);
25 //显示
26 void showall(PNODE phead);
27 //查找
28 PNODE findit(PNODE phead,void *pfind);
29 //获取内存信息
30 void getinfo(PNODE phead);
31 //释放所有内存
32 PNODE deleteall(PNODE phead);
33 
34 void *mymalloc(size_t size);
35 void myfree(void *p);
36 void *myrealloc(void *p, size_t size);

mem.cpp

  1 #include "mem.h"
  2 struct LinkNode *phead = NULL;
  3 
  4 //插入一个数据
  5 PNODE addback(PNODE phead, struct MEM *pmem)
  6 {
  7     //开辟一个结点
  8     PNODE pnew = (PNODE)malloc(sizeof(node));
  9     pnew->pmem = pmem;
 10     pnew->pNext = NULL;
 11 
 12     if (phead == NULL)
 13     {
 14         phead = pnew;
 15     }
 16     else
 17     {
 18         //备份首地址
 19         PNODE ptemp = phead;
 20         while (ptemp->pNext != NULL)
 21         {
 22             ptemp = ptemp->pNext;
 23         }
 24         ptemp->pNext = pnew;
 25     }
 26     return phead;
 27 }
 28 
 29 //修改一个指定的内存结构体
 30 PNODE change(PNODE phead, void *pfind, struct MEM *pnewmem)
 31 {
 32     for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
 33     {
 34         if (ptmp->pmem->p == pfind)
 35         {
 36             ptmp->pmem->p = pnewmem->p;
 37             ptmp->pmem->size = pnewmem->size;
 38             return phead;
 39         }
 40     }
 41     return phead;
 42 }
 43 
 44 //删除一个结点
 45 PNODE deletenode(PNODE phead, void *paddr)
 46 {
 47     //p2保存p1的前一个地址
 48     PNODE p1, p2;
 49     p1 = p2 = NULL;
 50 
 51     p1 = phead;
 52     while (p1 != NULL)
 53     {
 54         if (p1->pmem->p == paddr)
 55         {
 56             break;
 57         }
 58         else
 59         {
 60             p2 = p1;
 61             p1 = p1->pNext;//备份上一个
 62         }
 63     }
 64 
 65     if (p1 != phead)
 66     {
 67         p2->pNext = p1->pNext;
 68         free(p1);
 69     }
 70     else
 71     {
 72         phead = phead->pNext;
 73         free(p1);
 74     }
 75 
 76     return phead;
 77 }
 78 
 79 //显示所有数据
 80 void showall(PNODE phead)
 81 {
 82     if (phead == NULL)
 83     {
 84         printf("-------------------------------------------------------------------------\n\n");
 85         return;
 86     }
 87     else
 88     {
 89         printf("内存地址=%p     内存大小=%d\n", phead->pmem->p, phead->pmem->size);
 90         showall(phead->pNext);
 91     }
 92 }
 93 
 94 //查找
 95 PNODE findit(PNODE phead, void *pfind)
 96 {
 97     for (PNODE ptmp = phead; ptmp != NULL; ptmp = ptmp->pNext)
 98     {
 99         if (ptmp->pmem->p == pfind)
100         {
101             return ptmp;
102         }
103     }
104     return NULL;
105 }
106 
107 //获取信息
108 void getinfo(PNODE phead)
109 {
110     if (phead == NULL)
111     {
112         printf("目前一共0个地址在堆上,一共消耗0个字节的内存\n");
113         printf("-------------------------------------------------------------------------\n\n");
114         return;
115     }
116 
117     int i = 0;//多少个地址
118     int j = 0;//多少个字节
119     for (PNODE p = phead; p != NULL; p = p->pNext)
120     {
121         i++;
122         j += p->pmem->size;
123         printf("内存地址=%p     内存大小=%d\n", p->pmem->p, p->pmem->size);
124     }
125     printf("目前一共%d个地址在堆上,一共消耗%d个字节的内存\n", i, j);
126     printf("-------------------------------------------------------------------------\n\n");
127 }
128 
129 //释放所有内存
130 PNODE deleteall(PNODE phead)
131 {
132     printf("释放所有内存\n");
133     printf("-------------------------------------------------------------------------\n\n");
134     PNODE p1 = NULL;
135     PNODE p2 = NULL;
136     p1 = phead;
137     while (p1 != NULL)
138     {
139         p2 = p1->pNext;
140         free(p1->pmem->p);
141         p1->pmem->p = NULL;
142         free(p1);
143         p1 = p2;
144     }
145 
146     return NULL;
147     
148 }
149 
150 
151 void *mymalloc(size_t size)
152 {
153     void *p = malloc(size);
154     printf("分配内存        分配的地址%p    大小%d\n", p, size);
155     printf("-------------------------------------------------------------------------\n\n");
156     //创建一个结点,并且初始化,出入内存管理链表
157     struct MEM *pmem = (struct MEM*)malloc(sizeof(struct MEM));
158     pmem->p = p;
159     pmem->size = size;
160     phead = addback(phead, pmem);
161     return p;
162 }
163 
164 void myfree(void *p)
165 {
166     printf("\n内存地址%p释放\n", p);
167     printf("-------------------------------------------------------------------------\n\n");
168     PNODE px = findit(phead, p);
169     if (px == NULL)
170     {
171         return;
172     }
173     else
174     {
175         phead = deletenode(phead, p);//删除
176         free(p);
177     }
178 }
179 
180 void *myrealloc(void *p, size_t size)
181 {
182     
183     void *pt = realloc(p, size);
184     printf("内存地址%p重新分配到%p,大小%d\n",p, pt,size);
185     printf("-------------------------------------------------------------------------\n\n");
186     struct MEM mymem;
187     mymem.p = pt;
188     mymem.size = size;
189     phead = change(phead, p, &mymem);
190     return pt;
191 }

main.c

#include "mem.h"

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

void main()
{
    void *p1 = malloc(1024*1024*100);
    void *p2 = malloc(1024 * 1024 * 100);
    void *p3 = malloc(1024 * 1024 * 300);
    getinfo(phead);
    realloc(p1, 100);
    getinfo(phead);
    free(p3);
    getinfo(phead);
    phead = deleteall(phead);
    getinfo(phead);
    system("pause");
}

 

转载于:https://www.cnblogs.com/xiaochi/p/8399211.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值