在c++程序中,内存管理中经常隐藏着很深的bug。 虽然我们一般可以采用vector,string,map等容器自动管理内存,但涉及多态,继承的时候也不可避免的要手动管理,c++标准库中提供的auto_ptr能一定程度上帮助我们。auto_ptr用法:1.需要包含头文件2.Constructor:explicit auto_ptr(X* p = 0) throw();将指针p交给auto_ptr对象托管3.Copy constructor:auto_ptr(const auto_ptr&) throw();template auto_ptr(const auto_ptr& a) throw();指针的托管权会发生转移4.Destructor: ~auto_ptr();释放指针p指向的空间5.提供了两个成员函数X* get() const throw();//返回保存的指针,对象中仍保留指针X* release() const throw();//返回保存的指针,对象中不保留指针
auto_ptr实现关键点1.利用特点”栈上对象在离开作用范围时会自动析构”2.对于动态分配的内存,其作用范围是程序员手动控制的,这给程序员带来了方便但也不可避免疏忽造成的内存泄漏,毕竟只有编译器是最可靠的。3.auto_ptr通过在栈上构建一个对象a,对象a中wrap了动态分配内存的指针p,所有对指针p的操作都转为对对象a的操作。而在a的析构函数中会自动释放p的空间,而该析构函数是编译器自动调用的,无需程序员操心。
多说无益,看一个最实用的例子:
分析:1.如果采用方案1,那么必须考虑到函数在因throw异常的时候释放所分配的内存。这样造成的结果是在每个分支处都要很小心的手动 delete pTC;2.如果采用方案2,那就无需操心何时释放内存,不管foo()因何原因退出,栈上对象pTC的析构函数都将调用,因此托管在之中的指针所指的内存必然安全释放。注意:
至此,智能指针的优点已经很明了了。但是要注意使用中的一个陷阱,那就是指针的托管权是会转移的。例如在上例中,如果auto_ptr pTC(new TC);auto_ptr pTC1=pTC;那么,pTC1将拥有该指针,而pTC没有了,如果再用pTC去引用,必然导致内存错误。要避免这个问题,可以考虑使用采用了引用计数的智能指针,例如boost::shared_ptr等个人观点1.vc++库中的智能指针auto_ptr本不像都像前面介绍的那样auto_ptr pTC(new TC);auto_ptr pTC1=pTC;其中pTC指针并没有被托管,其地址还是指向new TC 的。但是并没有出现同一个指针释放两次的问题。2.VC中的 auto_ptr是一个对象,和内置指针是不一样的,它没有支持测试智能指针NULL的功能。auto_ptr<TestC> p;if(p == NULL); 并没有办法通过编译。3.并不支持将智能指针转化为内置指针,如:void print(TestC* p)