2

我的问题有两个部分:

  • 是否有可能,如果在分配内存之后但在释放内存之前发生段错误,这会泄漏内存(也就是说,内存永远不会被释放导致内存泄漏)?
  • 如果是这样,有没有办法确保在发生段错误时清理分配的内存?

我一直在阅读 C++ 中的内存管理,但找不到任何关于我的具体问题的信息。

4

5 回答 5

5

如果发生段错误,操作系统负责清理程序持有的所有资源。

编辑:

无论您的程序如何终止,现代操作系统都会清理任何泄漏的内存。内存只会在程序的生命周期内泄漏。大多数操作系统还会清理许多其他类型的资源,例如打开的文件和套接字连接。

于 2012-06-18T16:32:19.280 回答
4

是否有可能,如果在分配内存之后但在释放内存之前发生段错误,这会泄漏内存(也就是说,内存永远不会被释放导致内存泄漏)?

是和否:崩溃的进程应该完全由操作系统绑定。但是请考虑您的进程产生的其他进程:它们可能不会完全终止。但是通常这些不应该占用太多资源,但这可能会因您的程序而异。见http://en.wikipedia.org/wiki/Zombie_process

如果是这样,有没有办法确保在发生段错误时清理分配的内存?

如果程序不是关键的(这意味着如果它崩溃就没有生命危险)我建议修复分段错误。如果您确实需要能够处理分段错误,请参阅此主题的答案:如何在 Linux 中捕获分段错误?

更新:请注意,尽管可以处理 SIGSEGV 信号(并在程序流中继续),但它不是一种安全的依赖方式,因为 - 正如下面的评论中所指出的 - 它是未定义的行为,意味着不同的平台/compilers/... 可能会有不同的反应。

因此,通过任何方式可能修复分段错误(以及 Windows 上的访问冲突)都应该具有第一优先级。仍然使用建议的解决方案以这种方式处理信号必须经过彻底测试,如果放入生产代码中,您必须了解它并得出任何后果 - 这可能会有所不同并取决于您的要求,因此我不会命名。

于 2012-06-18T16:40:08.093 回答
2

C++ 标准不关心段错误(这是特定于平台的事情)。

在实践中,这真的取决于你做什么,以及你对“内存泄漏”的定义是什么。理论上,您可以为 seg-fault 信号注册一个处理程序,您可以在其中进行所有必要的清理。但是,无论如何,任何现代操作系统都会自动清除终止进程。

于 2012-06-18T16:31:55.680 回答
0

现代操作系统将应用程序的内存分开,以便能够在它们之后进行清理。分段错误的问题是它们通常只在出现问题时发生。此时,默认行为是关闭应用程序,因为它不再按预期运行。

同样,除非在某些奇怪的情况下,您的应用程序可能已经做了一些您无法解释的事情,如果它遇到了分段错误。因此,“清理”几乎是不可能的。为了保证可接受的回滚状态,仔细使用类似于事务数据库的内存并不是不可能的,但是这样做(并且取决于级别的细粒度)可能会非常乏味。

一个更实用的版本可能是在应用程序组件之间提供您自己的沙盒类型,并在组件死机时重新启动它,将其恢复到可接受的先前保存状态。这样你就可以刷新它所有分配的内存并让它从头开始。但是,您仍然会丢失截至上一个检查点尚未保存的任何数据。

于 2012-06-18T16:51:17.923 回答
0

一,有系统负责清理的资源。其中之一是记忆。您不必担心在段错误上永久泄漏 RAM。

二是存在系统不负责清理的资源。您可以编写一个程序,将其 pid 插入数据库并在关闭时将其删除。这不会因段错误而被删除。您可以 1) 添加一个处理程序来清理这种非系统资源,或者 2) 从一开始就修复程序中的错误。

于 2012-06-18T16:34:27.407 回答