1

我花了一些时间编写应用程序进行练习,并且我喜欢在整个过程中使用智能指针,以避免在我忘记删除某些内容时发生内存泄漏。同时,我也喜欢使用异常来报告构造函数中的失败并尝试处理它。但是,当它不能时,我希望它通过调用 assert() 或 exit() 退出该位置的程序。但是,使用 msvc 中的 crtdbg 库时,它会报告来自智能指针的内存泄漏,该智能指针具有动态分配给它们的任何内容。这对我来说意味着两件事之一。1) 智能指针永远不会超出分配它们的范围,也永远不会释放,从而导致一些内存泄漏,或者 2) crtdbg 没有捕获释放,因为它没有在 main 处退出。页面虽然,使用 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 在程序开始时将捕获来自任何出口点的泄漏,​​我仍然使用它得到内存泄漏错误。

所以我向你们提出的问题是,内存实际上会在退出或断言时被释放吗?如果没有,我是否可以从 std::shared_ptr 派生并实现我自己的解决方案来编目动态分配的对象,以便在调用之前释放退出或断言,还是对于更简单的解决方案来说工作量太大?

4

2 回答 2

6

当程序退出时,内存无论如何都会被操作系统回收,所以如果泄漏让你担心,它不应该。

但是,如果您的析构函数中有逻辑,并且必须销毁对象 -exit显式调用会绕过所有释放。一种解决方法是抛出一个异常,您将调用 exit,将其捕获main并返回。

#include "stdlib.h"

void foo()
{
   //exit(0);
   throw killException();
}

int main
{
   try
   {
      foo();
   }
   catch (killException& ex)
   {
      //exit program calling destructors
      return EXIT_FAILURE;
   }
}
于 2012-07-30T19:53:24.563 回答
2

真正的问题不在于内存,而在于其他资源。操作系统将(在大多数情况下,除非您正在运行嵌入式系统)在进程终止时从进程中恢复内存,因此内存不会在操作系统中泄漏。实际问题可能与您的流程外部的其他资源有关,这些资源可能需要在您的流程完成之前释放......

无论如何,您为什么更愿意abortexit不愿让异常传播?一般来说,您应该只处理您想要管理的异常并让其他异常通过。虽然您可能无法从中恢复,但您的呼叫者实际上可能能够恢复。通过捕获异常并当场退出程序,您将删除用户的处理选择。

于 2012-07-30T19:58:33.987 回答