C / C ++编程中是否需要全局析构函数?

时间:2016-04-08 01:52:50

标签: c++ c

__do_global_ctors_aux函数在程序初始化时执行全局对象构造。

__do_global_dtors_aux函数在程序退出时执行全局对象销毁。

问题是“__do_global_dtors_aux是否必要?”

程序退出后,OS应回收全局对象的内存。 虽然程序员可能想在析构函数中输出一些结果或消息,但我认为这可以在代码中的其他显式位置完成。除此之外,全局析构函数对我来说似乎是多余的。我想念一下吗?

更具体地说,非对象类型变量的销毁既不会影响当前程序行为,也不会影响其他系统资源。当程序退出C和C ++程序时,它会触发'__do_global_dtors_aux'函数吗?

在使用gcc或g ++编译的以下程序的程序集中有'__do_global_dtors_aux'标签。但我不确定它是否会被运行。

示例:

#include <stdio.h>

int a[100];

void func(unsigned int i)
{
    if (i < 100)
        printf("a[%d] = %d\n", i, a[i]);
}

int main()
{
    func(30);
    return 0;
}

对不好的措辞感到抱歉。

3 个答案:

答案 0 :(得分:1)

C ++标准要求在程序终止之前调用全局变量的析构函数,它们的构造顺序相反。在C中,当程序终止时,还有一些必需的操作(例如刷新和关闭文件)。

有些对象可以管理内存以外的资源。锁定互斥锁(或文件)并在没有正确清理的情况下终止的程序会给使用相同互斥锁(或文件)的其他程序带来麻烦。

此外,并非所有操作系统都从终止进程中回收内存。

答案 1 :(得分:1)

有两个更重要的问题需要提出,而不是“是必要的全局析构者”:

  • 全局析构函数有用吗?
  • 可以依赖全局析构函数吗?

对于后者,答案最重点是 NO 。程序可以通过多种方式在没有任何机会执行任何操作的情况下死亡(例如类Unix系统上的_exitSIGKILL)。即使atexitsigaction也不允许您正常展开堆栈。

那就是说,我认为如果你必须使用全局变量(它通常是一个非常好的主意而不是),它们的析构函数将是有用的调用,以便您可以使用valgrind等工具更轻松地跟踪资源问题。

答案 2 :(得分:0)

不仅在进程退出后由OS回收全局对象,而且为此进程分配了所有内存。从设计的角度来看,至少__do_global_ctors_aux / __ do_global_dtors_aux是好的。发送__do_global_dtors_aux会让人感到困惑,感觉不好。作为开发人员,我们不关心__do_global_ctors_aux / __ do_global_ctors_aux,通常我们专注于构造函数/析构函数。并且在进程退出之前释放所有内存是良好的编程习惯。