Chinaunix

标题: 异常对象是程序结束才被释放????!!! [打印本页]

作者: 飞灰橙    时间: 2007-11-09 17:10
标题: 异常对象是程序结束才被释放????!!!
原文见:
http://blog.csdn.net/mulinb/archive/2007/08/29/1763240.aspx
其中写到:9)        throw出的对象称为异常对象(exception object),由编译器管理,catch接受到的对象如果不是引用或指针的话,则进行对象拷贝。但是异常对象是程序结束才被释放。

异常对象是程序结束才被释放,这句话说错了吧
作者: anthony1983    时间: 2007-11-09 17:22
没啥问题吧,那你觉得什么时候被释放呢,自己写个例子看看什么时候被析构的吧
作者: yuanchengjun    时间: 2007-11-09 17:30
标题: 我猜,
try的时候,保留所有寄存器状态,按照函数一层层调用,先后入栈;
可能所有catch都是当作函数处理,就好象函数重载一样,因异常不同而调用不同catch;
当throw的时候,保存的寄存器状态出栈,回复寄存器,那样就能直接跳回到try,然后匹配catch;
如果没有匹配到,保存的寄存器状态出栈,……
直到有匹配的catch,如果没有,就……

[ 本帖最后由 yuanchengjun 于 2007-11-9 17:33 编辑 ]
作者: 飞灰橙    时间: 2007-11-09 20:50
楼上两位,写这么一个代码,
如果异常对象要到程序结束才释放,那么这个代码立刻就能将内存耗尽。显然不是这样的。

  1. struct exc
  2. {
  3.     int *p;
  4.     exc()
  5.     {
  6.         p = new int;
  7.     }
  8.     ~exc()
  9.     {
  10.         delete p;
  11.     }
  12. };


  13. while ( 1 )
  14. {
  15.      try
  16.      {
  17.           throw exc();
  18.      }
  19.      catch ( exc const &e )
  20.      {
  21.      }
  22. }
复制代码

作者: anthony1983    时间: 2007-11-09 22:39
  你都捕获了,当然释放了
作者: tyc611    时间: 2007-11-09 22:53
显然不是这样的嘛,异常对象一旦被捕获不再抛出,它就可以释放了(也应当立即释放,不能让它占着坑吧,呵呵)

写个测试代码:

  1. #include <iostream>
  2. #include <exception>
  3. using namespace std;

  4. class MyException: public exception
  5. {
  6. public:
  7.     MyException() {
  8.         num = ++max;
  9.         cout << "Constructor " << num << endl;
  10.     }
  11.    
  12.     MyException(const MyException &) {
  13.         num = ++max;
  14.         cout << "Copy Constructor" << num << endl;
  15.     }
  16.    
  17.     ~MyException() throw() {
  18.         cout << "Destructor " << num << endl;
  19.     }
  20.    
  21.     static void* operator new (size_t size) {
  22.         cout << "new in MyException" << endl;
  23.         return ::operator new(size);
  24.     }
  25.    
  26.     static void operator delete (void* p) {
  27.         cout << "delete in MyException" << endl;
  28.         ::operator delete(p);
  29.     }
  30.    
  31. private:
  32.     static int max;
  33.     int num;
  34. };

  35. int MyException::max = 0;

  36. void func1()
  37. {
  38.     throw MyException();
  39. }

  40. void func2()
  41. {
  42.     func1();
  43. }

  44. void func3()
  45. {
  46.     func2();
  47. }

  48. void func4()
  49. {
  50.     try {
  51.         func3();
  52.     } catch (const MyException &e) {
  53.         throw;
  54.     }
  55. }

  56. int main()
  57. {
  58.     try {
  59.         func4();
  60.     } catch (MyException e) {
  61.     }
  62.    
  63.     char ch;
  64.     cin >> ch;
  65.    
  66.     return 0;
  67. }
复制代码

运行结果:
Constructor 1
Copy Constructor2
Destructor 2
Destructor 1
q

Terminated with return code 0
Press any key to continue ...

由输出可见,此编译器实现(MinGW)可能是将异常对象分配在堆上,异常捕获后如果不再抛出则释放对象




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2