C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 共享库中静态函数成员的销毁顺序大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在探索与单身人士相关的Boost.serialization中一个非常棘手的错误.对于上下文:Boost 1.65更改了单例的实现,打破了is_destructed通知,导致程序退出或库卸载时出现段错误.提升1.66“固定”这个,但泄漏记忆.

单例代码(与此问题相关)归结为:

template<class T> struct singleton{
    T& inst(){
        static T t;
        return t;
    }
}

使用静态成员函数变量可以避免使用static init fiasco,但仍然存在与销毁相同的问题.

然而,Finding C++ static initialization order problems显示代码如何解决:当A的Ctor使用B时,B将首先被构造,因此最后被破坏.这也在Destruction order of static objects in C++中说明.(析构函数的完成以与构造函数完成相反的顺序发生)

到现在为止还挺好. Boost.serialization现在使用类型为extended_type_info_typEID< T>的多个单体.在另一个单独的std :: multiset< const bs :: typEID_system :: extended_type_info_typEID_0 *,...>中注册usertype T的一些元数据.这是通过使用extended_type_info_typEID_0的构造函数中的multiset(假设来自此处的所有单例)来完成的.在extended_type_info_typEID_0的析构函数中,删除了多集中的条目.

这意味着我们完全具有上述情况,并且multiset应该比其他实例更长.

这在使用共享库时会中断.我有以下测试用例:

test_R_283_11845@ulti_singleton.cpp:

int f();
int g();

int main(int argc,char**){
  // Make sure symbols are used
  if(argc==8) return f();
  if(argc==9) return g();
}

multi_singleton1.cpp:
#include <boost/serialization/extended_type_info_typEID.hpp>

int f(){
  return 0 != boost::serialization::extended_type_info_typEID<int>::get_const_instance().get_key();
} 

multi_singleton2.cpp:
#include <boost/serialization/extended_type_info_typEID.hpp>

int g(){
  // Use different(!) type
  return 0 != boost::serialization::extended_type_info_typEID<float>::get_const_instance().get_key();
} 

Build with:

g++ multi_singleton1.cpp -lboost_serialization -fPIC -shared -olibmulti_singleton1.so
g++ multi_singleton2.cpp -lboost_serialization -fPIC -shared -olibmulti_singleton2.so
g++ test_R_283_11845@ulti_singleton.cpp -l. -lmulti_singleton1 -lmulti_singleton2

Run in valgrind:
valgrind ./a.out

可以看出,这会破坏Boost 1.65中的记忆.原因是我通过劫持和记录ctor / dtor调用来追踪混乱的顺序:

ctor 0x7f9f0aa074a0 std::multiset<const extended_type_info_typEID_0*>
ctor 0x7f9f0a7f63e0 extended_type_info_typEID<float>

ctor 0x7f9f0a7f64a0 std::multiset<const extended_type_info_typEID_0*>
ctor 0x7f9f0aa073e0 extended_type_info_typEID<int>

dtor 0x7f9f0aa073e0 extended_type_info_typEID<int>
dtor 0x7f9f0aa074a0 std::multiset<const extended_type_info_typEID_0*>
dtor 0x7f9f0a7f64a0 std::multiset<const extended_type_info_typEID_0*>
dtor 0x7f9f0a7f63e0 extended_type_info_typEID<float>

这是使用GCC 6.4,但与GCC 7.1相同.正如您所看到的那样,2个多重集合在第二个extended_type_info_typEID之前被一起销毁.

我错过了什么吗?这是C标准允许的吗?

解决方法

basic.start.term/3开始:

也:

大佬总结

以上是大佬教程为你收集整理的c – 共享库中静态函数成员的销毁顺序全部内容,希望文章能够帮你解决c – 共享库中静态函数成员的销毁顺序所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。