内存仍然可以访问错误修复,但为什么

Memory still reachable bug fixed, but why?

本文关键字:为什么 错误 访问 内存      更新时间:2023-10-16

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

有两个 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++有一些影响,但不如两者。

1. 为什么或如何"修复"此问题?

我不确定为什么不深入研究libstdc++代码,但我假设iostreams库分配的内存在整个程序的持续时间内保持分配,当它被分配到共享库中时,valgrind 报告为问题,而不是在主程序中分配时。

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

首先,我不知道为什么你想要一些"独立于标准库"的东西,而标准库可能正在分配仍然可以访问的内存。 解决方法是要么在任何地方根本不使用标准库,要么以不同的方式使用它。

其次,该"修复"是未定义的行为,因为您通过重新定义std::ios_base与 std lib 中的正确定义不同而违反了一个定义规则。

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

相关文章: