c++重载new操作符,防止内存泄露

在c++开发过程中,内存泄漏是令程序员最苦恼的事情,有时为了找到一个内存泄漏的地方,要调试很长时间。重载new操作符,往往是很多大型项目常用的防内存泄漏的手段。本人闲来无事,写了个new操作符重载的函数,大家互相学习,有不足之处还望大家给予指正。

上代码,就不做过多的解释啦。

  1 #ifndef _BASE_H_
  2 #define _BASE_H_
  3 
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <map>
  7 using namespace std;
  8 
  9 typedef struct {
 10     unsigned long address;
 11     unsigned long size;
 12     char file[64];
 13     unsigned long line;
 14 } ALLOC_INFO;
 15 
 16 typedef map<unsigned long, ALLOC_INFO*> AllocMap;
 17 
 18 AllocMap* allocMap;
 19 
 20 #ifdef _DEBUG
 21 #define DEBUG_NEW new(__FILE__, __LINE__)
 22 
 23 void AddTrack(unsigned long addr, unsigned long asize, const char *fname, unsigned long lnum) 
 24 { 
 25     ALLOC_INFO *info = new ALLOC_INFO();
 26     info->address = addr;
 27     strncpy(info->file, fname, 63);
 28     info->line = lnum;
 29     info->size = asize;
 30     if (!allocMap)
 31     {
 32         allocMap = new AllocMap;
 33     }
 34     allocMap->insert(make_pair(addr,info));
 35 }
 36 
 37 void RemoveTrack(unsigned long addr)
 38 {
 39     if(!allocMap || 0 == allocMap->size())
 40     {
 41         return;
 42     }
 43     AllocMap::iterator iter = allocMap->find(addr);
 44     if (iter != allocMap->end())
 45     {
 46         ALLOC_INFO* info = iter->second;
 47         delete info;
 48         allocMap->erase(iter);
 49     }
 50 }
 51 
 52 inline void * operator new(unsigned int size, const char *file, int line)
 53 {
 54     void *ptr = (void *)malloc(size);
 55     AddTrack((unsigned long)ptr, size, file, line);
 56     return(ptr);
 57 }
 58 
 59 inline void operator delete(void *p)
 60 {
 61     RemoveTrack((unsigned long)p);
 62     free(p);
 63 }
 64 
 65 inline void * operator new[](unsigned int size, const char *file, int line)
 66 {
 67     void *ptr = (void *)malloc(size);
 68     AddTrack((unsigned long)ptr, size, file, line);
 69     return(ptr);
 70 }
 71 
 72 inline void operator delete[](void *p)
 73 {
 74     RemoveTrack((unsigned long)p);
 75     free(p);
 76 }
 77 #else  // _DEBUG
 78 #define DEBUG_NEW new
 79 #endif // _DEBUG
 80 
 81 // 用于检测内存并做最后的内存清理
 82 void DumpUnfreed()
 83 {
 84     AllocMap::iterator iter;
 85     ALLOC_INFO* info;
 86     unsigned long totalSize = 0;
 87     if(!allocMap || 0 == allocMap->size())
 88     {
 89         return;
 90     }
 91 
 92     for(iter = allocMap->begin(); iter != allocMap->end(); iter++)
 93     {
 94         printf("%-50s: LINE %d, ADDRESS %d %d unfreed\n", iter->second->file, iter->second->line
 95                , iter->second->address, iter->second->size);
 96         totalSize += iter->second->size;
 97         info = iter->second;
 98         delete info;
 99     }
100     printf("----------------------------------------------------------- \n");
101     printf("Total Unfreed: %d bytes \n", totalSize);
102     delete allocMap;
103 };
104 
105 #endif // _BASE_H_
1 #include "base.h"
2 #define new DEBUG_NEW
3 
4 int main()
5 {
6     char* pszCeshi = new char[5];
7     DumpUnfreed();
8     return 0;
9 }

最终运行结果如下:

c:\c++\test\test\main.cpp                         : LINE 6, ADDRESS 6637816 5 unfreed
-----------------------------------------------------------
Total Unfreed: 5 bytes

有些编译器会报:warning C4291: “void *operator new(unsigned int,const char *,int)”: 未找到匹配的删除运算符;如果初始化引发异常,则不会释放内存

要防止这种报错,可以再定义两个delete方法。如下:

inline void operator delete(void *p , const char *file, int line)
{
    RemoveTrack((unsigned long)p);
    free(p);
}

inline void operator delete[](void *p, const char *file, int line)
{
    RemoveTrack((unsigned long)p);
    free(p);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能。本期专题将从内存管理、内存泄漏、内存回收这三个方面来探讨C++内存管理问题。 内容预览: 1 内 存管理 1.1 C++内存管理详解 1.1.1 内存分配方式 1.1.1.1 分配方式简介 1.1.1.2 明确区分堆与栈 1.1.1.3 堆和栈究竟有什么区别? 1.1.2 控制C++的内存分配 1.1.2.1 重载全局的new和delete操作符 1.1.2.2 为单个的类重载 new[ ]和delete[ ] 1.1.3 常见的内存错误及其对策 1.1.4 指针与数组的对比 1.1.4.1 修改内容 1.1.4.2 内容复制与比较 1.1.4.3 计算内存容量 1.1.5 指针参数是如何传递内存的? 1.1.6 杜绝“野指针” 1.1.7 有了malloc/free为什么还要new/delete? 1.1.8 内存耗尽怎么办? 1.1.9 malloc/free的使用要点 1.2 C++中的健壮指针和资源管理 1.2.1 第一条规则(RAII) 1.2.2 Smart Pointers 1.2.3 Resource Transfer 1.2.4 Strong Pointers 1.2.5 Parser 1.2.6 Transfer Semantics 1.2.7 Strong Vectors 1.2.8 Code Inspection 1.2.9 共享的所有权 1.2.10 所有权网络 2 内存泄漏 2.1 C++中动态内存分配引发问题的解决方案 2.2 如何对付内存泄漏? 2.3浅谈C/C++内存泄漏及其检测工具 2.3.1 内存泄漏的定义 2.3.2 内存泄漏的发生方式 2.3.3 检测内存泄漏 2.3.3.1 VC下内存泄漏的检测方法 2.3.3.2 使用BoundsChecker检测内存泄漏 2.3.3.3 使用Performance Monitor检测内存泄漏 3 探讨C++内存回收 3.1 C++内存对象大会战 3.1.1 基本概念 3.1.2 三种内存对象的比较 3.1.3 使用栈对象的意外收获 3.1.4 禁止产生堆对象 3.1.5 禁止产生栈对象 3.2 浅议C++ 中的垃圾回收方法

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值