在查看boost库时发现一个小文件checked_delete.hpp里面几个小函数,它的作用用很简短的话来说:防止未定义的行为造成delete时的内存泄露。实现如下:
template<class T> inline void checked_delete(T * x) { // intentionally complex - simplification causes regressions typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; (void) sizeof(type_must_be_complete); delete x; } template<class T> inline void checked_array_delete(T * x) { typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; (void) sizeof(type_must_be_complete); delete [] x; } template<class T> struct checked_deleter { typedef void result_type; typedef T * argument_type; void operator()(T * x) const { // boost:: disables ADL boost::checked_delete(x); } }; template<class T> struct checked_array_deleter { typedef void result_type; typedef T * argument_type; void operator()(T * x) const { boost::checked_array_delete(x); } };
先看看下面这一种用例:
// filename : object.h class Object { public: Object(); ~Object(); };
// filename : object.cpp #include <stdio.h> #include "object.h" Object::Object() { printf("%s ", "A::A()"); } Object::~Object() { printf("%s ", "A::~A()"); }
// filename : del.h class Object; void delete_obj(Object* obj) { delete obj; }
下面在main中实现我们的测试:
#include<iostream> #include "del.h" #include "object.h" #include<boost/checked_delete.hpp> #include<boost/make_shared.hpp> int main() { Object* p = new Object(); delete_obj(p); return 0; }
这样的代码实现delete方式是无法调用析构函数,所以就有了下面这一行
boost::checked_delete(p);
这样写就可以正常调用了,另外出于好奇,测试了一下使用shared_ptr,看情况如何:
boost::shared_ptr<Object> obj(new Object); boost::shared_ptr<Object> obj2(new Object[10], [](Object* pObj) { delete[] pObj; });
发现在程序结尾都顺利地调用了析构函数。
所以使用shared_ptr是很不错的选择,当然,使用checked_delete可能让你的代码更加明确是要释放内存的,代码也显得紧凑。