智能指针无法释放内存

时间:2013-06-01 08:35:10

标签: c++ pointers memory smart-pointers

我的智能指针实现如下所示,它不会在异常时释放内存..

template <class T>
class SMARTPOINTER
{
public:
   SMARTPOINTER(T* pointee) : SMART_POINTEE(pointee) {
    cout <<"\n Inside class SMARTPOINTER CONSTURCTOR \n";
   }

   ~SMARTPOINTER() {
     cout <<"\n Inside class SMARTPOINTER DESTRUCTOR \n";
      delete SMART_POINTEE;
   }

   T& operator*() const
   {
      cout <<"\n Inside class SMARTPOINTER operator* \n";
      return *SMART_POINTEE;
   }

   T* operator->() const
   {
      cout <<"\n Inside class SMARTPOINTER operator->()  \n";
      return SMART_POINTEE;
   }

private:
   T* SMART_POINTEE;

};

class Widget
{
public:

  Widget() {
      cout <<"\n Inside Widget CONSTRUCTOR \n";
  }

   void Fun() { 
     cout <<"\n Inside Widget::Fun() \n";
   }

  ~Widget() {
      cout <<"\n Inside Widget DESTRUCTOR \n";
  }

};

class THROWME{

};

int main() {

SMARTPOINTER<Widget> sp(new Widget);
sp->Fun();
throw new THROWME;
(*sp).Fun();

return 0 ;
}

我发现输出是

Inside Widget CONSTRUCTOR 

 Inside class SMARTPOINTER CONSTURCTOR 

 Inside class SMARTPOINTER operator->()  

 Inside Widget::Fun() 
uncaught exception of type THROWME*
Aborted.

据我所知,智能指针在这种情况下应该帮助我!!我没有发现通过智能指针调用Widget的破坏。

所以我必须在这里错过一些实现。

评论后阅读

尝试抓住我得到了我的结果。但我仍然不知道它是否正确的做法 代码更改

  int main() {
        try {
        SMARTPOINTER<Widget> sp(new Widget);
        sp->Fun();
        THROWME tm;
        throw tm;
        (*sp).Fun();
        }
        catch(...) {
          cout <<"\n **SOME EXCEPTION CAUGHT**  \n";
        }
        return 0 ;
        }

结果

 Inside Widget CONSTRUCTOR 

 Inside class SMARTPOINTER CONSTURCTOR 

 Inside class SMARTPOINTER operator->()  

 Inside Widget::Fun() 

 Inside class SMARTPOINTER DESTRUCTOR 

 Inside Widget DESTRUCTOR 

 **SOME EXCEPTION CAUGHT**

2 个答案:

答案 0 :(得分:4)

未调用析构函数,因为未处理的异常THROWME导致调用std::terminate。另请参阅this question,特别是接受答案中的第一个引文:

  

C ++ 11 15.2构造函数和析构函数[except.ctor]

     

1当控制从throw-expression传递给处理程序时,为自输入try块以来构造的所有自动对象调用析构函数。自动对象按照完成构造的相反顺序销毁。

由于没有try块来处理异常,因此不会调用析构函数。

答案 1 :(得分:4)

析构函数的调用是堆栈展开的一部分,当异常“冒泡”调用堆栈时... 除了,当异常未处理时完成。在这种情况下,堆栈是否展开is implementation-defined

  

如果在程序中找不到匹配的处理程序,则调用函数terminate()except.terminate)。在调用terminate()之前是否展开堆栈是实现定义的。

为了更优雅地处理这个问题,您可以使用函数try块:

int main()
try {
  // main body
} catch (...) {
  std::cerr << "Unhandled exception\n";
  std::terminate();
}

...虽然这会吞下异常并使其难以调试。