zoukankan      html  css  js  c++  java
  • 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);
    }


     

  • 相关阅读:
    Windows8.1 + Nvidia cuda8.0 + Vs2015
    读《鲜花帝国》有感
    oracle-sql书写
    oracle--聚合函数和case when结合使用
    oracle正则表达式
    oracle中case when使用
    oracle分区表之列表分区
    linux下oracl字符集修改(WE8ISO8859P1 --> ZHS16GBK)
    linux 下安装oracle数据库
    oracle学习笔记
  • 原文地址:https://www.cnblogs.com/osyun/p/2247319.html
Copyright © 2011-2022 走看看