gcc,c++:静态字符串成员变量导致堆损坏/分段错误
Posted
技术标签:
【中文标题】gcc,c++:静态字符串成员变量导致堆损坏/分段错误【英文标题】:gcc, c++: static string member variarible causes heap corruption/segmentation fault 【发布时间】:2010-08-19 15:09:14 【问题描述】:我有一个使用动态加载库的大型应用程序。在程序结束时终止它时会出现段错误或吐出一条消息“glibc 检测到损坏的双链表”。查看 valgrind 输出,我认为情况就是这样: 假设我们有三个文件:
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 out 表示该行存在无效的 free/delete/delete : 字符串 IfTrackerFile::AubFileName;
我不知道发生了什么。 非常感谢这方面的任何帮助/指导。
【问题讨论】:
使用静态库并非易事。将所有内容编译为共享库并让编译器对其进行排序。 【参考方案1】:我猜你最终得到了两个不同的IfTrackerFile::AubFileName
副本。一种是直接从utilities.a
将其拉入您的程序,另一种是在您动态加载dynamicallyloaded.so
时。我猜这让系统在程序关闭时破坏所有静态和全局对象感到困惑,而你最终调用了两次析构函数。
我认为您不应该以这种方式混合 .a 和 .so 文件。基本上,一个好的经验法则是永远不要将.so
文件与.a
链接,即使您将-fPIC
代码放在.a
中也是如此。
【讨论】:
【参考方案2】:这是在黑暗中拍摄的,但问题可能是全局对象。将类实例化为全局变量意味着该变量在调用 main() 之前被实例化。这意味着在 main() 开始之前调用构造函数,在 main 完成后调用析构函数。构造函数和析构函数的调用顺序也是不确定的。
我的建议是将所有全局对象(不是普通旧数据的全局变量 - POD - 类型)转换为在 main 开头实例化并在 main 结尾销毁的指针。
【讨论】:
以上是关于gcc,c++:静态字符串成员变量导致堆损坏/分段错误的主要内容,如果未能解决你的问题,请参考以下文章