在Linux上,为什么析构函数在C ++中的全局变量的共享实例上运行两次?

时间:2010-08-04 19:19:52

标签: c++ linux shared-libraries global-variables destructor

在Linux上我从定义全局变量的静态库中生成了一些C ++代码。此全局变量的单个实例在引用其符号的两个共享库之间共享。

当进程关闭并运行静态终止阶段时,我看到此共享实例上的析构函数运行了两次!大概每个库卸载一次。

这个问题与我最近在这里看到的另一个问题密切相关:related question。这听起来像是一样的行为,但没有讨论它为什么会发生。

有人知道这种行为背后的理论解释吗?

2 个答案:

答案 0 :(得分:2)

如果你拿一个裸指针并将它放在一个智能指针(两次)中,它会破坏两次,每次容器引用数量减少到零。

因此,如果您将裸指针传递到两个库中,那就可以了。每一个都将它放在一个共享指针对象中,每个对象都进行破坏。如果您可以在dtor期间看到堆栈回溯,那么应该会在两个库中显示它。

答案 1 :(得分:0)

C ++有一条称为“一个定义规则”的规则:

每个程序应该只包含该程序中使用的每个非内联函数或对象的一个​​定义;无需诊断。该定义可以在程序中明确显示,可以在标准或用户定义的库中找到,或者(在适当的时候)隐式定义(见12.1,12.4和12.8)。

维基百科有一个article,可以更详细地解释这一点。

您尚未在问题中发布代码,因此我无法确定您的情况,但在the question you linked to中,问题中的示例是在两个共享库中定义相同的变量。这违反了“一个定义规则”,这显然是动态链接器的最终化策略所依赖的,导致析构函数被调用两次。