重载new和delete方法实现c++内存安全.docxVIP

  • 6
  • 0
  • 约2.79千字
  • 约 4页
  • 2021-01-26 发布于天津
  • 举报
C++使用new关键字创建的对象,被分配到堆内存空间,然后得到对象地址,当程序复杂 庞大时容易发生访问地址 bug或内存泄露bug。为了避免内存泄露并在调试程序时找到内 存泄露的bug,可以重载new和delete函数,确保程序的内存安全。 new和delete关键字都可以作为 operator来重载。重载的 new函数规定一个参数 size_t表示需要在堆空间上分配的内存大小,可以认为等于 sizeof得到的大小,这个数值由 系统创建对象时传递来。一般的实现方法就是: [cpp] view plaincopyprint? #i nclude stdlib.h void* operator new( size_t type_size) { retur n malloc(type_size); } 继承的delete函数规定一个参数 void*表示要删除的对象地址,一般的实现方法就是: [cpp] view plaincopyprint? #i nclude stdlib.h void operator delete(void* obj_ptr) { free(obj_ptr); } 在这两个函数里加入一些调试代码, 监视对象的创建和删除,就能很快找到bug。对 于在函数堆栈上按值创建的对象则无需关心, 因为函数在堆栈上创建和删除对象不会调用重 载的new和delete方法。 对于修复特定的内存泄露 bug,这样做已经足够解决问题,然而我们可以做的更完美 一些。考虑一下 COM和类似的接口系统,为了正确的引用接口,调用者必须放弃使用 new 和delete,通过接口的AddRef和Release实现内存安全。然而这样带来的负面影响很大, 就 是接口必须由实现者完整实现, 一旦底层的接口实现被封装, 接口类就无法当做普通类来继 承,失去了面向对象编程的特性。而基于重载 new和delete,我们可以实现一个既可以用 new创建,delete删除,又可以用 AddRef()引用,Release()释放的类,这个类的基本功能封 装之后,可以当做普通的类被继承,而它和继承类都具有以下特性: 创建者只关心用new来创建,用delete删除,就能保证对象内存安全。 使用者只需要用 AddRef引用它,用Release删除它,也能保证对象内存安全。 这两种使用方式同时存在仍然可以保证内存安全。 这个类可以视为一种引用类型, 所以命名为reference_type,通过重载new和delete, 加上引用计数方法,最终得以实现。 [cpp] view plaincopyprint? #ifndef __REFERENCE_TYPE_HPP #defi ne __REFERENCE_TYPE_HPP #in cludeexcepti on #in cludestdlib.h struct __declspec (no vtable) referen ce_type { private: __int64 __ref_count; public: referen ce_type(): __ref_co un t(1) { } virtual ~referen ce_type() TOC \o 1-5 \h \z { this-__ref_cou nt--; } void _hold() { this-__ref_co un t++; } void _drop() { this-__ref_cou nt--; if(this-__ref_count = 0) { delete this; } void* operator new( size_t obj_size) TOC \o 1-5 \h \z { retur n malloc(obj_size); } void* operator new[]( size_t arr_size) throw(std::bad_alloc) { throw std::bad_alloc(); } void operator delete(void* obj_addr) { referen ce_type* obj_t = (referen ce_type*)obj_addr; if(obj_t-__ref_count = 0) { free(obj_addr); } } void operator delete[](void* arr_addr) throw(std::bad_alloc) { throw std::bad_alloc(); } }; #en dif 这个对象可以被 new和delete,同时也可以被引用和释放, _hold()相当于COM里的 AddRef(), _drop()相当于COM里的R

文档评论(0)

1亿VIP精品文档

相关文档