zoukankan      html  css  js  c++  java
  • 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个字节的内存
      ");
       6         printf("-------------------------------------------------------------------------
      
      ");
       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
      ", p->pmem->p, p->pmem->size);
      17     }
      18     printf("目前一共%d个地址在堆上,一共消耗%d个字节的内存
      ", i, j);
      19     printf("-------------------------------------------------------------------------
      
      ");
      20 }
    • 释放链表的所有内存
       1 PNODE deleteall(PNODE phead)
       2 {
       3     printf("释放所有内存
      ");
       4     printf("-------------------------------------------------------------------------
      
      ");
       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
      ", p, size);
       5     printf("-------------------------------------------------------------------------
      
      ");
       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("
      内存地址%p释放
      ", p);
       4     printf("-------------------------------------------------------------------------
      
      ");
       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
      ",p, pt,size);
       6     printf("-------------------------------------------------------------------------
      
      ");
       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("-------------------------------------------------------------------------
    
    ");
     85         return;
     86     }
     87     else
     88     {
     89         printf("内存地址=%p     内存大小=%d
    ", 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个字节的内存
    ");
    113         printf("-------------------------------------------------------------------------
    
    ");
    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
    ", p->pmem->p, p->pmem->size);
    124     }
    125     printf("目前一共%d个地址在堆上,一共消耗%d个字节的内存
    ", i, j);
    126     printf("-------------------------------------------------------------------------
    
    ");
    127 }
    128 
    129 //释放所有内存
    130 PNODE deleteall(PNODE phead)
    131 {
    132     printf("释放所有内存
    ");
    133     printf("-------------------------------------------------------------------------
    
    ");
    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
    ", p, size);
    155     printf("-------------------------------------------------------------------------
    
    ");
    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("
    内存地址%p释放
    ", p);
    167     printf("-------------------------------------------------------------------------
    
    ");
    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
    ",p, pt,size);
    185     printf("-------------------------------------------------------------------------
    
    ");
    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");
    }
  • 相关阅读:
    cloud_config学习_2
    layui的tab和form冲突
    layui+beetl实现三级菜单
    postgreSQL官网教程_管理表、类型
    08、异 常&包
    07、面向对象特征之多态&内部类
    06、面向对象特征之继承
    04、面向对象
    03、数组&内存划分
    02、函数
  • 原文地址:https://www.cnblogs.com/xiaochi/p/8399211.html
Copyright © 2011-2022 走看看