`

内存泄露 防止在程序关闭后还有忘记释放的内存

阅读更多
主要是解决自己分配的内存忘记释放的问题,自己定义了几个函数取代了malloc,calloc,realloc,free这几个函数,尽量跟原有用法一致。

 

头文件mypool.h

#ifndef _MYPOOL_H
#define _MYPOOL_H

struct Node
{
 struct Node *preNode;//前一个节点
 struct Node *nextNode;//后一个节点
 void **varAddr;//存储指针变量的地址
 int size;
 char freed;
};

struct Chain
{
 struct Node *first;
 struct Node *last;
 int size;
};
void InitChain();
struct Node* InitNode(struct Node *pn);
int Push(struct Node *pn);
int RemoveChain(void **id);
int FreeChain();


void* MyMalloc(void **p,int size);
void* MyCalloc(void **p,int nsize,int usize);
void* MyRealloc(void **p,int size);
void MyFree(void **p);
#endif

 

实现代码:mypool.c

 

/************************************************************************/

/*这些代码主要是实现对自己分配的内存的管理,主要是为了防止在程序关闭后还有忘记释放的内存;*/

/*这块代码并不涉及对内存区块的分配管理。*/

/* 作者:jackyvan ,Email:jackyyvan@gmail.com */

/************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mypool.h"

static struct Chain chain;//定义一个链表的静态变量



/*初始化链表*/
void InitChain()
{
 chain.first=NULL;
 chain.last=NULL;
 chain.size=0;
}
/*初始化一个链表上的节点*/
struct Node* InitNode(struct Node *pn)
{
 pn=malloc(sizeof(struct Node));
 if(pn==NULL)
  return NULL;
 pn->preNode=NULL;
 pn->nextNode=NULL;
 pn->freed=0;
 pn->varAddr=0;
 pn->size=0;
 return pn;
}
/*加入一个新的内存分配的节点*/
int Push(struct Node *pn)
{
 struct Node *last=chain.last;
 struct Node *first=chain.first;
 if(first==NULL)
 {
  chain.first=pn;
  chain.last=pn;
 }
 else
 {
  chain.last->nextNode=pn;
  pn->preNode=chain.last;
  chain.last=pn;
 }
 chain.size++;
 return 1;
}
/*
从链表中移除一个节点
*/
int RemoveChain(void **id)
{
 struct Node *first=chain.first;
 struct Node *tp1=NULL,*tp2=NULL;
 if(first==NULL)
  return 0;
 while(first)
 {
  
  if((long)first->varAddr==(long)id)
  {
   tp1=first->preNode;
   tp2=first->nextNode;
   if(tp1)
   {
    if(tp2)
    {
     tp1->nextNode=tp2;
     tp2->preNode=tp1;
    }
    else
    {
     tp1->nextNode=NULL;
     chain.last=tp1;
    }
   }
   else
   {
    tp2->preNode=NULL;
    chain.first=tp2;
   }
   free(first);
   chain.size--;
   break;
  }
  first=first->nextNode;
 }
 return 1;
}
/*清空链表*/
int FreeChain()
{
 struct Node *first=chain.first;
 struct Node *tp1=NULL;
 while(first)
 {
  tp1=first->nextNode;
  free((void *)*(first->varAddr));
  free(first);  
  first=tp1;
 }
 chain.first=NULL;
 chain.last=NULL;
 chain.size=0;
 return 1;
}
/*
自定义的malloc,calloc,realloc,free函数
void **p参数 是存储分配内存地址的变量的地址,根据这个地址与分配内存关联,进行管理
*/
void* MyMalloc(void **p,int size)
{
 struct Node *pn=NULL;
 (*p)=malloc(size); 
 if(p==NULL)
  return NULL;
 pn=InitNode(pn);
 if(pn==NULL)
  return NULL;
 pn->varAddr=p;
 pn->size=size;
 Push(pn);
 return (*p);
}
void* MyCalloc(void **p,int nsize,int usize)
{
 struct Node *pn=NULL;
 (*p)=calloc(nsize,usize); 
 if(p==NULL)
  return NULL;
 pn=InitNode(pn);
 if(pn==NULL)
  return NULL;
 pn->varAddr=p;
 pn->size=nsize*usize;
 Push(pn);
 return (*p);
}
void* MyRealloc(void **p,int size)
{
 struct Node *pn=NULL;
 (*p)=realloc((*p),size); 
 if(p==NULL)
  return NULL;
 pn=InitNode(pn);
 if(pn==NULL)
  return NULL;
 pn->varAddr=p;
 pn->size=size;
 RemoveChain(p);
 Push(pn);
 return (*p);
}

void MyFree(void **p)
{
 if((*p)==NULL)
  return;
 free((*p));//释放内存
 RemoveChain(p);//把相关节点从链表移除
}


int main()
{
 char *p=NULL;
 char *p2=NULL;
 int *p3=NULL;
 InitChain();
 p=MyCalloc(&p,100,sizeof(char));
 strcpy(p,"abcdefgh...");
 p2=MyMalloc(&p2,18*sizeof(char));
 p3=MyMalloc(&p3,10*sizeof(int));
 p3=MyRealloc(&p3,20*sizeof(int));
 MyFree(&p2);
 FreeChain();
 return 0;
}
分享到:
评论

相关推荐

    ado访问数据库内存泄露

    内存泄露是指程序在申请内存后,无法释放已申请的内存空间,久而久之,系统可用内存越来越少,可能导致系统性能下降甚至崩溃。 内存泄露的原因多种多样,对于ADO访问数据库时出现的情况,可能涉及到以下几个方面: ...

    测试系统内存泄露的工具

    内存泄露是指程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄露可能不明显,但随着时间的推移,这些未释放的内存会逐渐积累,最终导致系统性能下降。内存泄露通常由于程序员的疏忽或编程错误引起,例如...

    Windows CE 内存泄漏的检测和防止

    内存泄漏是指程序在申请内存后未能释放或者无法释放,导致这部分内存无法再次被使用的情况。长期的内存泄漏会导致系统可用内存不断减少,最终可能引起系统崩溃或性能严重下降。 #### 四、内存泄漏的原因分析 1. **...

    java内存泄露.pdf

    内存泄露指的是程序在申请内存后,无法释放不再使用的内存空间。在Java中,主要是针对堆内存的泄露,因为堆内存是程序员通过`new`关键字动态分配的,使用完毕后需通过`delete`或`System.gc()`进行回收。如果忘记释放...

    android内存泄露的检测和排查

    在计算机科学中,内存泄漏是指程序在申请内存后,无法释放已不再使用的内存空间。在Android系统中,由于资源有限,内存管理尤为重要。内存泄漏通常发生在静态变量、单例模式、匿名内部类、非静态内部类以及忘记解除...

    内存释放内存释放内存释放

    4. **智能指针**:C++中的智能指针(如`std::unique_ptr`、`std::shared_ptr`)可以自动管理内存,避免忘记释放内存的问题。 5. **内存池**:内存池是一种内存管理策略,预先分配一大块内存,然后按需从中分配小块...

    计算机网络课件 内存泄露 C++ 题目

    1. **忘记释放内存**:程序员在使用完动态分配的内存后忘记调用`delete`。 2. **未捕获的异常**:如果在`new`操作之后,`delete`之前抛出了异常,那么这部分内存可能无法被正常释放。 3. **空指针删除**:错误地使用...

    Java加载dll,导致Java进程内存泄露

    例如,如果使用`malloc`或`new`分配内存,但忘记调用`free`或`delete`释放,那么这些内存将在DLL被卸载后依然占用,导致Java进程中的内存泄露。此外,DLL可能创建全局变量、静态对象或者打开文件句柄等,这些在DLL...

    GDI内存泄漏工具查看

    1. 忘记释放GDI对象:程序员在创建GDI对象后,忘记调用相应的DeleteObject()函数进行释放。 2. 异常处理不当:在可能出现异常的代码块中创建了GDI对象,但异常发生后没有正确清理资源。 3. 循环引用:多个对象相互...

    VC内存泄漏检测工具-Visual Leak Detector

    内存泄漏是常见的编程错误之一,它指的是程序在分配内存后未能正确释放,随着时间的推移,这些未释放的内存会积累起来,导致系统资源耗尽,从而影响程序的稳定性和性能。为了解决这一问题,出现了各种内存泄漏检测...

    探究内存泄露-Part2-分析问题Java开发Java经验

    内存泄露是指程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄露可能看似无害,但随着时间推移,未释放的内存会不断积累,消耗掉系统可用资源,导致系统性能下降。 1. 对象引用不当:这是最常见的内存...

    ios程序 内存优化记录LOG日志-20130112

    但如果你在cell配置过程中创建了新的对象并忘记释放,或者持有对cell的强引用,会导致内存泄漏。确保在cell重用时正确处理对象。 5. `updateAlert`:这可能涉及显示警告或通知,创建这些UI元素时需注意及时释放。 ...

    什么是内存泄漏Java开发Java经验技巧共3页.pdf

    内存泄漏是指程序在申请内存后,无法释放已不再使用的内存空间,导致系统可用内存持续减少,从而影响程序性能,甚至可能导致程序崩溃。在Java中,由于垃圾回收机制的存在,内存管理相对容易,但并不意味着内存泄漏不...

    symbian内存检查工具HookLogger

    通常,内存泄露出现在忘记释放动态分配的内存,或者对象的所有权转移不当的情况下。修复这些泄露通常涉及: 1. **确保每次New都有对应的Delete**:检查代码,确保每分配一次内存,就正确地释放一次。 2. **正确处理...

    Flex内存泄露总结

    Flex内存泄露总结主要聚焦在Flash Player的垃圾回收机制和内存管理问题上,这对于优化Flex应用程序的性能至关重要。首先,我们要理解垃圾回收的基本原理。在Flash Player中,内存的释放工作由垃圾回收器负责,它是一...

    Java内存泄漏问题相关总结

    即使使用连接池,也应确保所有资源在使用完毕后被正确关闭,以防止Statement和Resultset对象导致的内存泄漏。 7. **内部类和外部模块引用**: 内部类的引用可能导致外部类对象无法被回收,而外部模块对内部对象的...

    android内存泄露

    内存泄露是指程序在申请内存后,无法释放已不再使用的内存空间。在Android系统中,由于Java的自动垃圾回收机制,开发者通常不会遇到像C++那样的显式内存管理问题。但是,由于某些原因,如静态变量、单例模式、匿名...

    Android App调试内存泄露之Cursor.zip

    在Android应用开发中,内存泄漏是一个非常重要的问题,它会导致应用程序性能下降,甚至崩溃。本话题将深入探讨如何针对特定的内存泄漏问题——Cursor泄漏进行调试。Cursor对象是Android数据库操作中的关键组件,用于...

    LOG4D XE5,修复内存泄露版本

    如果忘记释放或错误地释放了内存,就会产生内存泄露。LOG4D XE5修复版可能涉及了以下几个方面的改进: 1. **智能指针优化**:检查并修正了使用`TInterfacedObject`和`IInterface`的地方,确保智能指针在不再使用时...

    java内存管理问题及解决办法

    1. 使用弱引用或软引用,以便在需要时及时释放内存。 2. 注意避免循环引用,尤其是在使用集合类时。 3. 及时关闭不再使用的资源,如数据库连接、文件流等。 4. 使用内存分析工具,如VisualVM、MAT等,监控程序的内存...

Global site tag (gtag.js) - Google Analytics