【发布时间】:2013-10-11 17:25:40
【问题描述】:
我正在尝试使用共享库来构建模块化程序。
有两个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++ 有一些效果,但效果不如两者。
【问题讨论】:
-
最大的问题是:你为什么对在应用程序退出时释放内存如此挂念 - 操作系统本身将在微秒后释放内存?除非你只是在满足你的好奇心,否则这完全没有意义。在后一种情况下,调试器是你的朋友。跟踪分配了哪些内存以及释放了哪些内存,然后您应该看到哪些运行时代码调用了释放,甚至可以找出它没有被释放的原因。调试器,他们工作。
-
基本上,内存泄漏只是在应用程序运行时发生的泄漏。当应用程序退出时,它们不再泄漏。换句话说:如果它应该在应用程序的正常运行期间被释放,那么你就有了真正的泄漏。如果它在应用程序承诺退出时被释放,您不必担心。
-
@KubaOber 这正是我讨厌的态度。我不在乎操作系统在执行我的应用程序之后 做了什么。我关心我的应用程序。如果有任何一点点导致废话发生(泄漏,UB),我想消除它。没有人应该编写泄漏的代码。这是错误的来源。
-
@stefan:我认为你很幸福地没有意识到 Valgrind 带有一大堆“忽略这个和那个”。您所看到的基本上是列表中缺少的内容。当您禁用这些抑制时,输出将非常冗长,以至于处于无用的边缘。这个禁止列表完全是你所关注的东西,它基本上是通过运行在 your 代码中没有泄漏的合理程序并添加所有库泄漏来创建的到压制。
-
@KubaOber 我知道 valgrind 确实会产生误报,它只是另一个无法完美运行的软件(可以理解,因为它非常复杂)。我是一个完美主义者w.r.t。软件。如果我能理解一个问题,我就会解决它。如果我不能,我问直到我明白,然后解决它。这真是个问题。
标签: c++ linux memory-leaks g++ shared-libraries