嵌入式技术
看到的一个文章,有人用一个很简短的代码实现了内存检测工具,大家看看实用性如何?
工具特点
1 极度简单:34行代码实现,线程安全
2 入寝式检测:需要给现有重点怀疑的类添加一行入寝代码
3 只针对类类型: 动态数组需要使用更为复杂的技术,不在检测能力范围之内。考虑到大部分C++代码都以类实现代码,所以我认为这已经足够。
4 仅限于测试: 不可以用于正式代码。当我们发现有可能有内存泄露的时候,使用该工具入侵到当前代码。跑一段时间发现有没有内存泄露。发现泄露之后需要再次删除入侵代码。实现原理给类添加一个静态成员,这个成员在类对象复制控制的时候记录该对象创建(构造)了多少次,释放(析构)了多少次。在程序退出时向控制台输出统计结果。代码非常易于理解。
一些特殊的场景
1 服务端程序:服务端程序往往长时间运行不退出。但是我们的工具只有程序正确的退出才会给出统计结果。所以,你的服务端程序必须要能够(改造成)正常退出(可以使用Web接口,捕获信号,接受输入等方式)。
2 动态数组检测:如果历史代码里有大量的动态数组,使用原始指针来访问管理。那么这种情况下,该工具爱莫能助。我们认为这样的C++代码首先是不合理的。所以也不予支持。
程序效果
1 可靠:由于代码过于简单,所以库本身不会有问题。经历过多个产品的内存泄露检测工作。完美可信赖。
2 好用:只需要包含一个头文件即可。
代码如下:
#ifndef MEMORY_LEAK_CHECKER_H #define MEMORY_LEAK_CHECKER_H //memory checke library begin #include#include #include #include class object_usage_counter { public: object_usage_counter(const char* name) :m_name(name), m_counter(0) {}; ~object_usage_counter() { std::cout << "class " << m_name << " memory leak num = " << m_counter << std::endl; }; void inc() { ++m_counter; } void dec() { --m_counter; assert(m_counter >= 0); } private: std::atomic m_counter; std::string m_name; }; template class counter_by_copy { public: counter_by_copy() { m_the_only_object_for_one_class.inc(); } ~counter_by_copy() { m_the_only_object_for_one_class.dec(); } counter_by_copy(const counter_by_copy&) { m_the_only_object_for_one_class.inc(); } private: //the only object to count usage. static object_usage_counter m_the_only_object_for_one_class; }; //TIPS:template class's static member object can be define at the .h file template object_usage_counter counter_by_copy ::m_the_only_object_for_one_class(typeid(T).name()); //memory checke library end #endif // !MEMORY_LEAK_CHECKER_H //example usage /* class A { public: //A's copy control member functions call counter increasing or decreasing usage. counter_by_copy m_checker; }; */
示例代码如下:
#include "memory_leak_checker.hpp" #include#include #include #include class A { public: counter_by_copy m_checker; }; A* CreateA(void) { return new A; } void f(void) { auto p = new A; } int main(int argc, char* argv[]) { auto pa = new A;//leak 1 new A[5];//leak 5 auto p2 = CreateA(); delete p2; f();//leak 1 std::vector listA;//no leak for (int i = 0; i < 3; ++i) { listA.push_back(i);//no leak } std::cout << "test leack 7" << std::endl; }
运行结果
全部0条评论
快来发表一下你的评论吧 !