Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用exit(1)时释放内存,c++;_C++_Memory Leaks_Exit - Fatal编程技术网

C++ 使用exit(1)时释放内存,c++;

C++ 使用exit(1)时释放内存,c++;,c++,memory-leaks,exit,C++,Memory Leaks,Exit,我正在做一项学校作业,我们被告知,每当我们有意见时 错误我们应该打印一条消息并退出程序。显然我使用了出口(1),但是 问题是使用此函数时内存泄漏。我不明白为什么——我使用的每个变量都在堆栈上,而不是堆上 我应该做些什么来防止这些内存泄漏? 谢谢 使用退出功能时,您的程序将终止,并释放其分配的所有内存。不会有内存泄漏 编辑: 从您的评论中,我可以理解您担心您的对象在终止之前没有被销毁(即它们的析构函数没有被调用)。但是,这并不构成内存泄漏,因为内存是由进程释放并提供给系统的。如果您指望对象析构函数

我正在做一项学校作业,我们被告知,每当我们有意见时 错误我们应该打印一条消息并退出程序。显然我使用了出口(1),但是 问题是使用此函数时内存泄漏。我不明白为什么——我使用的每个变量都在堆栈上,而不是堆上

我应该做些什么来防止这些内存泄漏?
谢谢

使用退出功能时,您的程序将终止,并释放其分配的所有内存。不会有内存泄漏

编辑: 从您的评论中,我可以理解您担心您的对象在终止之前没有被销毁(即它们的析构函数没有被调用)。但是,这并不构成内存泄漏,因为内存是由进程释放并提供给系统的。如果您指望对象析构函数执行对工作流重要的操作,我建议返回错误代码,而不是使用
exit
,并将该错误代码传播到main()

编辑2:


根据该标准,在销毁具有静态存储持续时间的对象期间调用exit()会导致未定义的行为。你在这么做吗?

你没有真正的内存泄漏。当程序终止时,操作系统将释放程序使用的所有内存。

解决方案是根本不使用
exit()
。您使用RAII(使用类进行资源管理)编写程序,并在出现问题时抛出异常。然后,由于调用了析构函数,所有内存都会被回收。

exit不会调用任何基于堆栈的对象的析构函数,因此如果这些对象在内部分配了任何内存,则会泄漏内存

实际上,这可能并不重要,因为任何可能的操作系统都会回收内存。但是如果析构函数要做其他的事情,你就会有问题


因为这个原因,退出并不能真正地与C++混合。您最好允许您的程序从main返回到exit,或者如果您需要从引发异常的内部函数退出,这将导致调用堆栈解缠,从而调用析构函数。

好吧,我只在使用它时发生内存泄漏。事实上,我确定这会导致内存泄漏我不确定我是否理解。。。调用exit时,程序终止,内存释放。你能在你认为有内存泄漏的地方发布一些代码吗?@yotamoo你“肯定知道”的依据是什么?你在用什么工具吗?@Ahe:你可能想重读你链接的帖子。这是关于一个特定工具可能报告的链接,因为内存没有在工具认为应该释放的时候释放。一旦应用程序死掉,它与操作系统的行为无关。顺便说一句,这是为了在应用程序运行后进行清理,回收所有内存并关闭文件句柄等等。除此之外,操作系统不能通过
malloc
泄露14个字节或任何内容,它甚至不知道
malloc
。它一次给程序一整页(通常是4KB),然后让他们在他们认为合适的时候分发。那么,你是说多次运行该程序会填满你的RAM吗?你怎么知道你有内存泄漏?如果你提供一些你认为包含内存泄漏的最小代码,这将更容易回答。你似乎对术语感到困惑。内存泄漏是指在进程运行时累积更多已分配内存(不再使用)。在终止进程的情况下,这是毫无意义的。然而,通过正常终止,您可以得到一些关于是否存在内存泄漏的指示,即通过检查是否仍有已分配的块。有些工具可以做到这一点。调用
exit
(或
abort
)是毫无意义的,在这里不调用本地对象的析构函数。我怀疑你的观点是建立在这样一张毫无意义的支票上的。@Alf P.Steinbach:最佳答案!:)@阿尔夫:一点也不“毫无意义”。程序终止时内存仍在使用,这表明代码中存在漏洞。例如,这就是
valgrind
所关注的。而且,是的,.@Let_Me_Be:不,我没有混淆它们。“这将导致调用堆栈展开”-前提是捕获到异常。如果不是,则由实现定义堆栈是否展开。所以类似于
int main(){try{/*program goes here*/}catch(const ExitException&e){return e.value;}catch(…){return 1;}return 0;}
的东西就起了作用,其中ExitException是我为了保存退出代码而发明的一个异常类。显然,日志记录也很有用,在调试模式下,如果调试器对未捕获的异常执行任何有用的操作,那么最好不要捕获异常。实际上,我使用的实现即使对于未捕获的异常也会释放堆栈,但如果可以避免,则不应依赖未定义的行为。@JohnB:这不是未定义的行为。它是实现定义的。我已经多次看到抛出一个未捕获的异常而立即终止。明白-我认为公平地说,如果你想在退出时正确清理,调用exit()可能不应该是你的第一选择,尽管@Tomalak Geret'kal-好吧。。。只要程序运行,内存泄漏就会存在。对于小程序来说,不注意这一点是一种不好的做法。对于长期程序,如服务、内核模块,甚至是像Internet Explorer这样只运行了很长时间的程序,它们都可以,而且大多数都存在内存泄漏。了解一些关于OSs虚拟内存机制的信息,了解为什么当程序终止时,所有的内存都释放回OS。C++对虚拟内存或特定的OSS一无所知。A我