Windows下return,exit和ExitProcess的区别和分析
通常,我们为了使自己的程序结束,会在主函数中使用return或调用exit()。在windows下还有ExitProcess()和TerminateProcess()等函数。
本文的目的是比较以上几种结束程序的方式的区别,并分析其原理。
首先我们用一个例子来说明几种结束方式的区别。
测试代码如下:
#include
#include
#include
class Test
{
public:
Test (int i) {m_i=i; printf ("construct %d\n", m_i);};
~Test () {printf ("destruct %d\n", m_i);};
private:
int m_i;
};
Test t_1 (1);
int main(int argc, char* argv[])
{
Test t_2 (2);
printf("Hello World!\n");
// return 0;
// exit (0);
// ExitProcess (0);
}
我们的目标是察看两种结束方式有什么不同。
程序在运行的结果为:
使用return 0结束时:
construct 1
construct 2
Hello World!
destruct 2
destruct 1
使用exit (0)结束时:
construct 1
construct 2
Hello World!
destruct 1
使用ExitProcess (0)结束时:
construct 1
construct 2
Hello World!
从结果上我们可以看出来,采用return来结束进程可以正确的析构全局和局部对象。而采用exit()来结束进程时全局对象可以正确析构,但局部对象没有正确析构。采用ExitProcess(0)结束时全局和局部对象都没有正确析构。
为什么会出现这样的情况呢?
《Windows核心编程》中我们可以得到以下解释:
"当主线程的进入点函数(WinMain、wWinMain、main或wmain)返回时,它将返回给C/C++运行期启动代码,它能够正确地清楚该进程使用的所有C运行期资源。当C运行期资源被释放之后,C运行期启动代码就显式的调用ExitProcess,并将进入点函数返回的值传递给它。"
在Windows下,return 0 的实际执行过程是:
先析构main函数内的局部对象。
返回至调用main的函数。
调用exit函数,由exit函数调用doexit函数,在doexit函数中完成对全局对象的析构。
最后调用ExitProcess结束进程。
所以,ExitProcess不负责任何对象的析构,exit只负责析构全局对象,return 0可以析构局部对象并调用exit,因此能析构全部对象。
Windows下return,exit和ExitProcess的区别和分析的更多相关文章
- windows下使用MYSQL的mysqldumpslow进行慢日志分析
1.首先安装好perl环境. 2.在dos环境中,切换到perl目录中,例如我的目录是 dos 命令 cd c:\Perl\bin 3.在此目录输入perl mysqldumpslow的路径\mysq ...
- c/c++中system函数在Linux和windows下区别
windows 在windows下的system函数中命令可以不区别大小写! 功 能: 发出一个DOS命令 #include <stdlib.h> int system(char *com ...
- windows 下 Mutex和Critical Section 区别和使用
Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量.对象或内存空间的访问.下面是其主要的异同点(不同的地方用黑色表示). Mutex Cri ...
- C++和C在linux下 和在windows下有什么区别?
一.函数库的区别 linux下的C函数库和windows下的函数库系统调用的机制不一样,Glibc包含了主要的C库.这个库提供了基本例程,用于分配内存.搜索目录.打开关闭文件.读写文件.字串处理.模式 ...
- 从Docker在Linux和Windows下的区别简单理解Docker的层次结构
上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序.本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的W ...
- linux和windows下icmp的区别
实验方式:先从linux虚拟机ping windows主机,然后从windows主机ping linux虚拟机,在pc上采用wireshark抓包. 如下(只保留了关键信息) 可以看到linux发出的 ...
- Linux 和 Windows 下实现多进程的方式以及管道操作
一.多进程 1.windows 多进程 使用 #include<windows.h> 下面的 BOOL CreateProcess( LPCWSTR pszImageName, LPCWS ...
- windows下的getopt/getoptlong函数
windows下的getopt/getoptlong函数 getopt/getopt_long函数是GNU C中的函数,在linux编程中很常用到.这里就不介绍了. windows下没有找到类似的函数 ...
- Windows下的进程【一】
什么是进程?进程就是一个正在运行的程序的实例,由两部分组成: 内核对象.操作系统用内核对象对进程进行管理,内核对象是操作系统保存进程统计信息的地方. 地址空间.其中包含所有可执行文件或DLL模块的代码 ...
随机推荐
- Java Hibernate中的悲观锁和乐观锁的实现
锁(locking) 业务逻辑的实现过程中,往往需要保证数据访问的排他性.如在金融系统的日终结算 处理中,我们希望针对某个cut-off时间点的数据进行处理,而不希望在结算进行过程中 (可能是几秒种, ...
- hostnamectl 修改 CentOS7 主机名
hostnamectl 控制主机名 # 显示状态 hostnamectl Static hostname: centos Icon name: computer-vm Chassis: vm Mach ...
- Sublime Text 3 Mac常用快捷键与注意事项
大多数情况下容易忘记的快捷键,在此整理了一下. 编辑快捷键:cmd+L:选择行(重复按下将下一行加入选择):cmd+D:选择词(重复按下时多重选择相同的词进行多重编辑):cmd+shift+D 复制光 ...
- freemarker写入word【未完,待续】
. java基于feemarker 生成word文档
- 流媒体技术学习笔记之(十八)Ubuntu 16.04.3 如何编译 FFmpeg 记录
官方文档:https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu 一.最简单安装: apt-get install ffmpeg 二.安装最新版本 大 ...
- C#调用C++导出类的一个实例
一直认为带导出类dll的只有VC自己可以调用,其它编程语言无法调用,今天看到一篇文章才知道自己错了.https://blog.csdn.net/huiyouyongdeyu2011/article/d ...
- 清除 SQL Server Management Studio 服务器名称历史记录
Ø 前言 在开发过程中,经常使用 SQL Server Management Studio 连接本地或远程 SQL Server 服务器,时间长了可能有些名称就不用了或者重复了,SQL Server ...
- luogu 2827 蚯蚓 单调队列/优先队列
易知可利用优先队列选取最大值: 但是通过分析可知,先取出的蚯蚓分开后仍然要比后分的长,所以可直接利用单调队列找队头即可,分三个单调队列,分别找未切割,切割,切割2三种情况 #include<bi ...
- Mysql 基础导入导出
Mysql 导出数据库: mysqldump -u root -p 数据库 > 导出库名.sql mysqldump -u 用户名 -p 数据库名 表名 > 导出表名.sql 示例:mys ...
- 用Nodejs连接MySQL
转载,原地址:http://blog.fens.me/nodejs-mysql-intro/ 前言 MySQL是一款常用的开源数据库产品,通常也是免费数据库的首选.查了一下NPM列表,发现Nodejs ...