在动态加载的库中将内存分配到哪里?

时间:2014-07-08 14:47:51

标签: c++ c memory memory-management shared-libraries

我一直想知道.. 根据这张表: http://ilay.org/yann/articles/mem/process_map.png(对不起它的法语部分) 内存分配在不同的内存空间中,具体取决于程序的哪个部分正在分配它。

因此,如果我在程序中创建一个对象,它将在程序中分配。如果动态分配内存,它将在堆中,以及动态加载对象的“链接”。

我的问题是: 从动态加载的库中动态分配的内存属于哪里?

如果我有包含此内容的库:

extern "C" Object* create_Object()
{
   return new Object();
}

class Object
{
    int a;
    int* b;
    ...
}

我的对象会在堆中还是在链接中分配?

我的猜测是堆,但我有一段代码让我怀疑它。 我正在开发一个Cpp脚本系统,我的脚本被编译为共享库,加载到我的程序中,并在每次重新编译脚本时重新加载。我们的想法是在卸载脚本之前保存脚本的状态,并在动态加载的对象的新实例中恢复其内容。如果我的动态加载对象的字段被映射到堆中,将指针保存到数据就足够了,但是如果创建的类是在内存的“链接”段中分配的,那么当我恢复内容时,我的指针会指向在未分配的内存上,这将使我的程序完全不稳定,情况就是这样......

所以我不知道。内存中的哪个是我的“对象”实例? “a”在哪里,是不是动态分配的?如果我动态地分配它,“b”的内容在哪里?在我的例子中?

我希望新的分配在堆中,无论在哪里调用new,并且来自Object的变量a和b也将在堆中分配,因为它是从动态分配的对象实例化的,但它是只有猜测,我想肯定地知道......

我也想知道一旦我关闭共享库,我的Object实例会发生什么。再一次,如果它在堆中,我应该没有任何问题来访问我的对象,但由于我没有符号,我想这个对象将被分配,但是相当不适合,因为我无法解析其成员。

我希望你可以帮助我=)

2 个答案:

答案 0 :(得分:2)

我认为对象数据安全地存储在堆上,即使在dlclose()之后(除非更改了C ++动态空间分配器)。

但是你肯定会在调用虚拟方法时遇到问题。虚拟表将指向不再可用的文本区域。并且C ++没有提供重新绑定虚拟方法的方法;不是我知道的。

如果你真的需要,你可以:

  1. 将您的班级定义更改为struct;
  2. 将所有虚拟方法声明为此结构中的指针;
  3. 让你的加载/卸载例程提供绑定(即为每个分配的对象中的每个指针分配每个实际函数)。
  4. 当然,您将跟踪所有对象实例。当然,你可以有一个指针,指向一个表,由库提供的表本身;这个单指针仍然必须手动反弹。

答案 1 :(得分:1)

没有从动态加载的库中动态分配的内存。动态分配的内存意味着它通过调用malloc进行分配。程序中只有一个malloc,对它的调用是否来自程序代码中加载了原始可执行文件或可共享目标文件的部分并不重要。

注意:从实际角度来看,new通常是通过调用malloc来实现的,因此,同样的考虑适用于此。

注意,在Win32上,情况可能完全不同:DLL可能在其自己的堆上运行其唯一的malloc(当然,free)。这样的DLL中的内存malloc'必须在同一个DLL中free'。