【问题标题】:Is there any way to make sure my function to be the last function to be called?有什么方法可以确保我的函数是最后一个被调用的函数?
【发布时间】:2014-07-04 06:27:59
【问题描述】:

我已经覆盖了全局 new/delete 以捕获内存泄漏。当进程退出时,我需要调用assertNoMemoryLeak来断言new分配的所有内存都已释放。

但似乎我不能让assertNoMemoryLeak 成为我的进程中调用的最后一个函数,因为某些全局变量析构函数将是最后一个。

  1. atexit 不起作用,原因如下。 AFAIK,当调用构造函数时,由 gcc 生成的全局析构函数将被推送到 atexit 列表,而且我也无法在启动期间让我的 push 'assertNoMemoryLeak' sn-p 在此之前运行,所以我的 assertNoMemoryLeak 仍然不会运行作为最后一个函数。

  2. 另一种解决方法是将new/delete 信息写入文件,然后在进程退出后分析文件(使用脚本)。我不想这样做,因为为每个开发人员自动这样做很复杂。

那么有什么方法可以让assertNoMemoryLeak 成为最后一个调用的函数?

【问题讨论】:

  • 我已经删除了 C++ 标签,因为这个问题显然与 C 无关。
  • 不是答案,但为什么不使用 Valgrind 来代替detect memory leaks
  • 如果你只有一个翻译单元,你可以创建一个在所有其他全局对象之前构造的全局对象,并让它在构造函数中调用atexit(),在这种情况下,标准保证在所有全局对象被销毁之前,不会调用注册函数。但是,如果有多个翻译单元,您就不太走运了。
  • 但是,如果您使用的是 GCC,则可以使用 init_priority attribute 强制您的 atexit-registering 对象首先初始化,但 requires linker support 因此可能不适用于 android。
  • @T.C.:“让它在构造函数中调用atexit()”——或者更简单地说,在析构函数中完成工作。

标签: c++ memory-leaks


【解决方案1】:

如果查找和管理所有全局静态对象是可行的,那么您可以创建一个全局静态对象,其工作是按所需顺序构造和销毁所有其他全局对象。如果您无法控制所有这些,或者它们位于不同库中的太多不同位置,那么这将不切实际。

您可以通过将所有全局静态对象更改为指针,或使它们成为一个主对象的成员,或在没有全局对象的情况下重写代码来做到这一点。关键是消除任何您无法控制的启动和关闭,然后在您控制的这个全局对象的析构函数中在适当的时间运行您的断言检查。

【讨论】:

  • 如果您创建全局指针,您可以通过将旧名称定义为对取消引用的指针的引用来避免更改其他代码,假设主启动对象在任何其他代码使用它之前正确初始化了该指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 2016-09-19
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多