exit and ~destructor

今天在 c++ programming language 上看到这样描述

 

If a program is terminated using the standard library function exit() ,  the destructors for constructed static objects are called. However, if the program is terminated using the standard library function abort they are not. Note that this implies that exit() does not terminate a program immediately. Calling exit() in a destructor may cause an infinite recursion.

 

查询msdn有如下解释:

The exit and _exit functions terminate the calling process. exit calls, in last-in-first-out (LIFO) order, the functions registered by atexit and _onexit, then flushes all file buffers before terminating the process. _exit terminates the process without processing atexit or _onexit or flushing stream buffers

 

When you call the exit or _exit functions, the destructors for any temporary or automatic objects that exist at the time of the call are not called. An automatic object is an object that is defined in a function where the object is not declared to be static. A temporary object is an object created by the compiler. To destroy an automatic object before calling exit or _exit, explicitly call the destructor for the object, as follows:

 

myObject.myClass::~myClass();

 

网上有对此的讨论http://www.programfan.com/club/showtxt.asp?id=288606 ,各执一词,所用vs版本不同也有不同结果

 

 

用vs2008编写程序测试

#include"stdlib.h"


class ex
{
public:
 ~ex() {
  exit(1); 
 }  // It may cause overflow;
};

int main()
{
 ex a;
 ex a1;
 exit(2);
}

上边程序结束时返回值为2,在exit(1)处设断点,没有被执行,可见如上所述 automatic varible‘s destructor 没有被调用

 

 


class ex
{
public:
 ~ex() {
  exit(1); 
 }  // It may cause overflow;
};

 

static ex a;

static ex a2;

int main()
{
 exit(2);
}

上边程序结束时返回值为1,在exit(1)处设断点,exit(1)被执行两次,可见如上所述destructors for constructed static objects are called。 但是也没有stack overflow。

 

有人在连接中分析了在vs2005上产生overflow的原因,可以参考一下

 

 

#include <cstdlib>

class A {
public:
    ~A() {
         exit(1);
    }
};

int  main() {
    A a1;        // 运行无错
     static A a2; //  stack overflow
     return 0;
}


分析:
1. 若写了A a1;这句,则在main函数返回之前,会调用a1的析构函数,于是转到exit(1);。也就是说,并不会等到main函数返回,整个程序就会结束。于是main函数的返回值就被忽略了。证据:不加A a1;时,整个程序返回零。加了以后整个程序返回1。以下是两种不同情况下,按F5运行后Debug窗口输出内容的最后一行。
The program '[7828] 001.exe: Native' has exited with code 0 (0x0).
The program '[6664] 001.exe: Native' has exited with code 1 (0x1).
2. 若写了static A a2;这句,则在运行的时候出现错误:stack overflow。C++标准中规定,exit函数的功能是先释放各种资源,然后退出。这里的“各种资源”就包括了全局变量和static变量,所以,exit函数会调用a2的析构函数。当main函数返回之后,程序即将结束,此时会调用a2的析构函数。a2的析构函数会调用exit,exit又会调用a2的析构函数,这样无限的调用下去,最终导致堆栈溢出。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值