众所周知,C/C++里面的内存管理的确是一件十分痛苦的事情,分配了一段内存的时候若忘了撤销必定会造成内存泄漏。另外如果显示写了撤销的语句也不一定绝对不会出错。
代码:
void fun()
{
vector<string> v;
string s;
while (cin >> s)
v.push_back(s);
string *p = new string[v.size()];
if (0 == p)
throw bad_alloc("memory allocate error!");
delete[] p;
}
vector和第一个静态string是函数内的局部变量,在函数执行完毕以后会自动运行它们各自的析构函数撤销。在发生异常的时候,会自动清除异常之前的局部对象,但是不会清楚动态分配的对象。所以要是上面的代码发生异常,程序将不会运行到delete语句,则动态分配的string对象不会被撤销,造成内存泄漏。 C++里面有一种异常安全技术,即程序发生了异常依然是安全的。这一技术常称为"资源分配即初始化“,简称RAII。而STL标准库里面的auto_ptr类即是上面技术的一种实现,在头文件memory中定义。 auto_ptr保存的是一个指针,可以将指向new出来的内存的指针赋给auto_ptr对象,当auto_ptr对象超出作用域或者另外撤销的时候,就会自动运行析构函数撤销指针所指向的对象。
上面的代码则可以这样写:auto_ptr<string> ptr(new string[v.size()];
二,auto_ptr源码
template <class T>
class auto_ptr
{
public:
explicit auto_ptr(T *p = 0); //防止隐式转换
template <class U>
auto_ptr(auto_ptr<U>& rhs); //任何兼容的auto_ptr作为一个新的auto_ptr初值
~auto_ptr();
template <class U>
auto_ptr<T>& operator = (auto_ptr<U>& rhs);
T& operator * () const;
T* operator -> () const;
T* get()const; //返回保存的指针
T* release(); //返回保存指针,并使auto_ptr成为未绑定的状态
void reset(T *p = 0); //重新绑定
private:
T *pointee;
template <class U>
friend class auto_ptr<U>;
};
template <class T>
inline auto_ptr<T>::auto_ptr(T *p) //让所有的auto_ptr classes都成为另一个auto_ptr的友元
:pointee(p)
{}
template <class T>
template <class U>
inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
:pointee(rhs.release())
{}
template <class T>
inline auto_ptr<T>::~auto_ptr()
{delete pointee;} //这里不是delete[],所以autuo_ptr不能保存动态数组
//不是简单的赋值,而是将实参绑定的对象转移到当前对象
template <class T>
template <class U>
inline auto_ptr<T>& auto_ptr<T>::operator = (auto_ptr<U>& rhs)
{
if (this != &rhs) reset(rhs.release());
return *this;
}
template <class T>
inline T& auto_ptr<T>::operator * () const
{return *pointee;}
template <class T>
inline T* auto_ptr<T>::operator -> () const
{return pointee;}
template <class T>
inline T* auto_ptr<T>::get() const
{return pointee;}
template <class T>
inline T* auto_ptr<T>::release()
{
T *oldptr = pointee;
pointee = 0;
return oldptr;
}
template <class T>
inline void auto_ptr<T>::reset(T *p)
{
//未处理p参数非法的情况
if (pointee != p){
delete pointee;
pointee = p;
}
}
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppsl/2008522/117689.html)