2010-08-19 66 views
0

我有一个使用动态加载库的大应用程序。在程序结束时终止它或者segfaults或者吐出一条消息“glibc检测到损坏的双链表”。望着Valgrind的输出,我认为是这样的话是什么: 让我们说我们有三个文件:gcc,C++:static string member variarible导致堆损坏/分段错误

utilities.c  - compiled with -fPIC and used ar and ranlib to create utilities.a. 
dynamicallyloaded.c- compiled with -fPIC and -shared and linked with utlities.a to generate dynamicallyloaded.so 
main.c    - compiled with -fPIC and linked with utilities.a to create main. main dynamically loads and uses dynamicallyloaded.so . 
utilities.h  - delclared a class IfTrackerFile with AubFileName as a static string member like static string   AubFileName; 

utilities.cpp  - defines the static variable: string IfTrackerFile::AubFileName; 

的valgrind出来说有是无效的自由/删除/删除就行了: 串IfTrackerFile :: AubFileName;

我不知道发生了什么事。 真正感谢在这方面的任何帮助/方向。

+0

使用静态库不是微不足道的。将所有内容编译为共享库,并让编译器将其整理出来。 – 2010-08-19 15:32:17

回答

0

这是在黑暗中拍摄的照片,但问题可能是全局对象。将类实例化为全局变量意味着该变量在调用main()之前被实例化。这意味着构造函数在main()开始之前被调用并且在main完成之后调用析构函数。构造函数和析构函数被调用的顺序也是不确定的。

我的建议是将所有全局对象(全局变量不是普通的旧数据 - POD类型)转换为在main的开始处实例化并在main的末尾销毁的指针。

1

我的猜测是你最终得到了IfTrackerFile::AubFileName的两个不同副本。一个是从utilities.a直接在程序中拉动它,另一个是动态加载dynamicallyloaded.so。我猜测,这使得系统在程序关闭时将所有静态和全局对象破坏,并最终调用析构函数两次。

我不认为你应该以这种方式混合.a和.so文件。基本上,一个好的经验法则是永远不要链接.so文件与.a,即使您将-fPIC代码放在.a中。