重载operator new实现检测内存泄漏是否可行
行与不行,就凭我这水平,说出来未免显示太过自大。不还,我还想根据自己的代码来讨论这个问题。
重载operator new来检测内存只的办法,那就是在new的时候记录指针地址及文件名、行号,在delete的时候取消记录。到最后程序结束,还有哪些指针未释放,则为泄漏。
第一步,你得重载operator new,或者也可以重写。在http://www.cplusplus.com/reference/new/operator%20new/中指明new有三种形式,因为我们还分配数组,故还有new[]这个函数也要重载。那么有6种。原文中指明“The allocating versions ((1) and (2)) are also replaceable:”,则说明我们只能重载4个函数(也必须,不然检测不到部分内存分配,没有意义)。由于placement new不会有内存泄漏,也不能重载,可以不管。
#include <iostream>
#include <cstdlib> using namespace std; inline void *operator new[](std::size_t size, const char *file, int line)
{
std::cout << "memory allocate at " << file << " line " << line << std::endl;
void *p = ::operator new(size);// operator new (size,std::nothrow)
return p;
} inline void * operator new(std::size_t size, const char *file, int line)
{
std::cout << "memory allocate at " << file << " line " << line << std::endl;
void *p = ::operator new(size);
return p;
} inline void operator delete(void *p)
{
std::cout << "free" << std::endl;
free(p);
} inline void operator delete[] (void *p)
{
std::cout << "free[]" << std::endl;
free(p);
} #define new new(__FILE__, __LINE__) class TTest
{
public:
TTest(){ std::cout << "construct...." << std::endl; }
~TTest(){ std::cout << "destruct...." << std::endl; }
}; int main()
{
TTest *p = new TTest();
delete p; return ;
}
注意上面的代码中,因为懒,并没有重载完4个函数。另外,注意new函数是重载,故可以调用::operator new,而delete函数是重写,再调::operator delete就递归成死循环了。不过这并不影响我说明问题。
结果:
memory allocate at ../test/main.cpp line
construct....
destruct....
free
按 <RETURN> 来关闭窗口...
看,已经知道分配的文件、行号,还能知道是否已分配,那么说明还是可行的。
可是,并不是所有的程序都是这么简单的。重载后,我们当然希望所来new的用法及参数都不用变。因为我们不希望已写的代码需要修改。从另一个方面说,如果用了第三方库,总不能一个个将别人的new替换成自己的函数。于是有了“#define new new(__FILE__, __LINE__)”这行代码,通过一个宏定义巧妙地将函数替换了。
new int()被替换成new(__FUNCTION__,__LINE__) int(),这样,原来的代码不变。但是,这个宏定义并不够巧妙。上面提到,new有三种形式,这个宏定义只能替换最常用的一种void* operator new (std::size_t size) throw (std::bad_alloc);对于其他则无能为力。
#include <iostream>
#include <cstdlib> using namespace std; inline void *operator new[](std::size_t size, const char *file, int line)
{
std::cout << "memory allocate at " << file << " line " << line << std::endl;
void *p = ::operator new(size);// operator new (size,std::nothrow)
return p;
} inline void * operator new(std::size_t size, const char *file, int line)
{
std::cout << "memory allocate at " << file << " line " << line << std::endl;
void *p = ::operator new(size);
return p;
} inline void operator delete(void *p)
{
std::cout << "free" << std::endl;
free(p);
} inline void operator delete[] (void *p)
{
std::cout << "free[]" << std::endl;
free(p);
} #define new new(__FILE__, __LINE__) class TTest
{
public:
TTest(){ std::cout << "construct...." << std::endl; }
~TTest(){ std::cout << "destruct...." << std::endl; }
}; int main()
{
char *buff[] = {'\0'};
TTest *p = new TTest();
delete p; p = new(buff) TTest(); return ;
}
显然,p = new(buff) TTest();调用了第三种new函数void* operator new (std::size_t size, void* ptr) throw();由于参数问题编译报错。其实,第二、三种new函数原型在STL、BOOST里很常用。所以这种替换并不适用。
由于我并不知道编译器#define new new(__FILE__, __LINE__)是怎么去解释这行代码的,故没法写出一个实现三种函数原型都能替换的宏定义。当然,如果你只想知道有没有内存泄漏,不需要知道文件名、行号,则重写new函数而不是重载是可行的。但感觉这也太鸡肋了。
不知道有没有大神能实现函数的替换,望指教。
重载operator new实现检测内存泄漏是否可行的更多相关文章
- 重载new和delete来检测内存泄漏
重载new和delete来检测内存泄漏 1. 简述 内存泄漏属于资源泄漏的一种,百度百科将内存泄漏分为四种:常发性内存泄漏.偶发性内存泄漏.一次性内存泄漏和隐式内存泄漏. 常发性指:内存泄漏的代 ...
- Qt creator 搭配 valgrind 检测内存泄漏
继上次重载operator new检测内存泄漏失败之后,妥协了.决定不管是否是准确指明哪一行代码出现内存泄漏,只要告诉我是否有泄漏就行了,这样就没有new替换的问题.在开发中,总是一个个小功能的开发. ...
- 如何在linux下检测内存泄漏
之前的文章应用 Valgrind 发现 Linux 程序的内存问题中介绍了利用Linux系统工具valgrind检测内存泄露的简单用法,本文实现了一个检测内存泄露的工具,包括了原理说明以及实现细节. ...
- Vc 检测内存泄漏
启用内存泄漏检测 检测内存泄漏是 C/c + + 调试器和 C 运行时库 (CRT) 的主要工具调试堆函数. 若要启用调试堆的所有函数,在 c + + 程序中,按以下顺序包含以下语句: C++复制 # ...
- 如何在linux下检测内存泄漏(转)
本文转自:http://www.ibm.com/developerworks/cn/linux/l-mleak/ 本文针对 linux 下的 C++ 程序的内存泄漏的检测方法及其实现进行探讨.其中包括 ...
- 面向开发的内存调试神器,如何使用ASAN检测内存泄漏、堆栈溢出等问题
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 介绍 如何使用 ASAN 检测内存泄漏 检测悬空指针访问 检测堆溢出 C++ 中的new/delete不匹配 检测栈 ...
- Android性能优化之利用LeakCanary检测内存泄漏及解决办法
前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...
- 使用Visual Leak Detector检测内存泄漏[转]
1.初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题 ...
- monkey检测内存泄漏
monkey中检查内存泄漏,实际上是对一个操作多次操作后看内存情况,内存泄漏具体的原理可百度,现在我们梳理检测内存泄漏的方法: 测试前你需要安装: 1.MAT分析工具 2.使用工具事实监控内存指标,现 ...
随机推荐
- hdu 4983 Goffi and GCD(欧拉函数)
Problem Description Goffi is doing his math homework and he finds an equality on his text book: gcd( ...
- iOS 原生二维码扫描,带扫描框和扫描过程动画
在代码中使用了相对布局框架Masonry 准备两张图片,一张是扫描边框,一张是扫描时的细线分别命名 scanFrame.png和scanLine.png并提前放入工程 导入相对布局头文件 #defin ...
- 正则表达式获取URL参数
使用到的正则表达式: [^\?&]?参数名=[^&]+ document.location.getURLPara = function (name) { var reg = new R ...
- 利用Excel批量高速发送电子邮件
利用Excel批量高速发送电子邮件,分两步: 1. 准备待发送的数据: a.) 打开Excel,新建Book1.xlsx b.) 填入以下的内容, 第一列:接收人,第二列:邮件标题,第三列:正文,第四 ...
- IOS的一个带动画的多项选择的控件(一)
先上效果图: 这个程序分2个层次,一个是顶部的带UITextField的bar,一个是下拉选择的view,下拉选择的view带有4个自己定义的UIView 我们先定义一个UIViewControlle ...
- C++11 lambda 表达式
C++11 新增了很多特性,lambda 表达式是其中之一,如果你想了解的 C++11 完整特性,建议去这里,这里,这里,还有这里看看.本文作为 5 月的最后一篇博客,将介绍 C++11 的 lamb ...
- My way to Python - Day04 - 模块
re模块 什么是正则表达式 正则表达式,英文叫做Regular Expression.简单说,正则表达式就是一组规则,用于实现字符串的查找,匹配,以实现关于字符串的相关操作,比如替换,删除等. 正则表 ...
- 利用iptables实现基于端口的网络流量统计
如何统计某个应用的网络流量(包括网络流入量和网络流出量)问题,可以转换成如何基于端口号进行网络流量统计的问题.大部分网络应用程序都是传输层及以上的协议,因此基于端口号(tcp, udp)统计网络流量基 ...
- ASP.net获取当前页面的文件名,参数,域名等方法
ASP.net后台获取当前页面的文件名 System.IO.Path.GetFileName(Request.Path).ToString(); 获取当前页面文件名,参数,域名等方法 假设当前页完整地 ...
- javascript构造函数+原形继承+作用域扩充
目前为止我认为这是最佳的声明对象的模式,将今天学到的东西写下 <script type="text/javascript"> function Constructor( ...