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

时间:2022-05-26 22:39:35

On Linux I have some generated C++ code from a static library that defines a global variable. A single instance of this global variable is shared between two shared libraries that refer to its symbol.

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

When the process shuts down and the static termination phase is run, I see that the destructor on this shared instance is run twice! Presumably once per library as each unloads.

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

This question is closely related to another I saw recently here: related question. This sounds like the same behavior, but there is no discussion about why it is happening.

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

Does anybody know the theoretical explanation behind this behavior?

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

2 个解决方案

#1


2  

If you take a naked pointer and place it in a smart pointer (twice), it will destruct twice, once for each container refcount falling to zero.

如果你拿一个裸指针并将它放在一个智能指针(两次),它将破坏两次,每次容器引用计数降至零。

So, if you pass the naked pointer into both libraries, that would do it. Each one puts it in a shared pointer object and each of those does the destruction. If you can see the stack backtrace during the dtor, that should show it happening in both of the libraries.

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

#2


0  

C++ has a rule called the "One Definition Rule":

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

Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8).

Wikipedia has an article that explains this in more detail.

*有一篇文章更详细地解释了这一点。

You haven't posted code in your question, so I can't be sure about your case, but in the question you linked to, the example in the question was defining the same variable in two shared libraries. This violated the "One Definition Rule", which apparently the dynamic linker's finalization strategy depends on, causing the destructor to be called twice.

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

#1


2  

If you take a naked pointer and place it in a smart pointer (twice), it will destruct twice, once for each container refcount falling to zero.

如果你拿一个裸指针并将它放在一个智能指针(两次),它将破坏两次,每次容器引用计数降至零。

So, if you pass the naked pointer into both libraries, that would do it. Each one puts it in a shared pointer object and each of those does the destruction. If you can see the stack backtrace during the dtor, that should show it happening in both of the libraries.

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

#2


0  

C++ has a rule called the "One Definition Rule":

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

Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8).

Wikipedia has an article that explains this in more detail.

*有一篇文章更详细地解释了这一点。

You haven't posted code in your question, so I can't be sure about your case, but in the question you linked to, the example in the question was defining the same variable in two shared libraries. This violated the "One Definition Rule", which apparently the dynamic linker's finalization strategy depends on, causing the destructor to be called twice.

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