6

我正在尝试使用共享库来构建模块化程序。

有两个 cpp 文件需要编译:

共享库,编译

g++ -fPIC -shared module.cpp -o module.so

//module.cpp
#include <iostream>

使用共享库的文件,编译

g++ src/main.cpp -ldl -o 二进制

或者

g++ -DFIX src/main.cpp -ldl -o 二进制

//main.cpp
#include <dlfcn.h>
#ifdef FIX
# include <iostream>
#endif

int main()
{
   void* h = dlopen("./module.so", RTLD_LAZY);
   if ( h )
   {
      dlclose(h);
   }
}

FIX未定义的情况下,valgrind 报告大量仍可访问的内存(5,373 字节),在FIX已定义的情况下,没有内存泄漏。

iostream在共享库中使用有什么问题?

g++-4.6、g++-4.7 和 g++-4.8 会出现此问题。g++-4.4 没有显示这种行为。遗憾的是,我没有其他编译器可供测试(因此我不想切换到 g++-4.4)。

更新:

使用附加标志编译共享库文件-static-libstdc++ -static-libgcc会减少泄漏块的数量,但不能完全减少。-static-libgcc单独没有效果,-static-libstdc++有一些效果,但不如两者都大。

4

1 回答 1

1

1. 此代码片段为何或如何“修复”问题?

我不确定为什么不深入研究 libstdc++ 代码,但我假设 iostreams 库分配的内存(在整个程序期间一直分配)在分配时被 valgrind 报告为问题共享库,但不是在主程序中分配时。

2. 什么等效的、独立的(来自标准库的)代码片段提供了相同的错误修复?

首先,当标准库可能正在分配仍然可访问的内存时,我不知道为什么你想要“独立于标准库”的东西解决方法是在任何地方都完全不使用标准库,或者以不同的方式使用它。

其次,“修复”是未定义的行为,因为您通过重新std::ios_base定义与 std lib 中的正确定义不同的方式违反了单一定义规则。

获得相同行为的正确方法是#include <iostream>在您的main.cpp文件中,包括<iostream>定义一个static std::ios_base::Init对象。或者,只是#include <ios>然后定义static变量(但不要重新定义std::ios_base类型),但这基本上就是<iostream>这样做的,所以你不妨使用它。

于 2013-10-06T16:40:10.293 回答