2010-04-12 19 views
4

我正在研究一个包含静态stl容器类的类“A”的项目。这个类包含在我的主程序和一个.so文件中。该类使用默认(隐式,未声明)的构造函数/析构函数。主程序使用dlopen()加载.so文件并在其析构函数中调用dlclose()。当glibc调用静态类成员变量的析构函数时,程序在主退出后崩溃。问题似乎是,当调用dlclose()时,将调用静态变量的析构函数,然后当main exits()glibc也调用析构函数时,会导致double free。我有2个问题,即:
1)在这种特殊情况下,为什么没有两个副本的静态变量(是的,我知道这听起来有些荒谬,但由于主程序和.so文件都有一个单独编译的'A',它们不应该每个都有吗?)
2)有没有什么办法可以解决这个问题,而不需要重写类'A'来不包含静态成员变量?动态库和主程序中的静态类变量

+0

是对中'dlclose()'从称为静态析构函数?我遇到了类似的问题,但在调用静态析构函数之前,代码段未映射。 – 2010-04-12 19:48:04

+1

你误解了这个问题 - 共享库获得自己的静态变量。 – 2010-04-12 19:58:35

+0

是的,他们这样做,当我查看符号表时,共享库确实有它自己的符号。但是它看起来好像没有使用.SO的符号。主程序中的符号调用静态构造函数和析构函数两次。这可能是由于extern“C”函数声明造成的一些不良名称变形的结果吗? – Paul 2010-04-13 17:04:29

回答

0

我相信STL类总是动态创建的,所以你实际上不能称它们为静态的。它们存在于堆上。如果成员被传递给一个函数,那么一个副本将被放入静态内存中。你必须让你自己的析构函数明确地删除stl。

+0

静态的,我的意思是静态链接(例如,我的主程序包含类'A'的代码的副本,我的.so包含类'A'的代码的副本)与静态前缀。 例如: A级 { public: 静态列表 slist; } – Paul 2010-04-13 03:48:57