Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
共享库内存空间 C++共享库是否有自己的内存空间?或者它是否共享调用进程“1”_C++_Memory_Memory Management_Shared Libraries - Fatal编程技术网

共享库内存空间 C++共享库是否有自己的内存空间?或者它是否共享调用进程“1”

共享库内存空间 C++共享库是否有自己的内存空间?或者它是否共享调用进程“1”,c++,memory,memory-management,shared-libraries,C++,Memory,Memory Management,Shared Libraries,我有一个共享库,其中包含一些类和包装函数。 其中一个包装函数是: libXXX_construct()初始化对象并返回指向所述对象的指针 在调用方程序中使用libXXX\u construct()后,对象放在哪里?它是在“调用方”内存空间中还是在库的内存空间中?所有共享库共享其进程的虚拟内存空间。(包括主可执行文件本身)您的对象存在于调用者的内存空间中(实际上是库和主可执行文件之间共享的一个内存空间)共享地址空间,以便您可以共享指针,但它们不共享分配器(至少在windows上不共享) 这意味着,

我有一个共享库,其中包含一些类和包装函数。 其中一个包装函数是:

libXXX_construct()
初始化对象并返回指向所述对象的指针


在调用方程序中使用
libXXX\u construct()
后,对象放在哪里?它是在“调用方”内存空间中还是在库的内存空间中?

所有共享库共享其进程的虚拟内存空间。(包括主可执行文件本身)

您的对象存在于调用者的内存空间中(实际上是库和主可执行文件之间共享的一个内存空间)

共享地址空间,以便您可以共享指针,但它们不共享分配器(至少在windows上不共享)


这意味着,如果调用new来分配共享库中的对象,则必须在同一库中调用delete,否则可能会发生奇怪的事情。

共享库的链接实例直接或间接共享链接到它的可执行文件实例的内存空间。对于Windows和类似UN*X的操作系统来说都是如此。请注意,这意味着共享库中的静态变量不是进程间通信的一种方式(很多人都这么认为)。

共享库与其主机进程具有相同的地址空间。必须是这样,否则你就不能将指针从一个模块传递到另一个模块,因为它们不能取消引用它们

但是,尽管它们位于相同的地址空间中,但这并不意味着它们都使用相同的内存管理器。结果是,如果您提供了一个代表调用者分配内存的函数,那么您应该提供相应的函数来释放该内存,例如,
libXXX\u destroy()

,除非另有规定,共享库将与托管它的进程共享内存。每个流程实例都将有自己的副本

但是,在Windows上,可以创建允许进程间通信的共享变量。你可以通过将它们放在正确的片段中来实现这一点。默认情况下,Windows使用两种类型的段:数据段是读/写非共享的,而代码段是只读可执行和共享的。但是,读写和共享属性是正交的。库中的共享读写段可用于存储共享变量,它将一直存在到最后一个进程退出

小心C++,因为即使在共享段中放置变量,也会在进程的开始和退出过程中运行构造函数和析构函数。


有关详细信息,请参阅Matt Pietrek。

的确,库在加载它的每个进程中都会耗尽内存。但是,至少在Windows下,当多个进程加载同一个DLL时,未修改的页面(包括所有代码页面)会悄悄地在后台共享。此外,它们在交换文件中不占用任何空间,因为它们由原始文件支持

我相信由于JIT编译,这对于.NET来说更为复杂,但对于NGENed程序集来说仍然如此

编辑


这是虚拟机的一个细节。但是,您也可以在DLL中创建一个要跨进程共享的段

如果链接到sharedlibrary的可执行文件也是共享库呢?是在内部创建的对象。因此,在main的同一内存空间中(调用后者。so),只有一个内存空间。默认情况下为True,但静态变量可用于在Windows上共享数据。请参阅我的答案了解详细信息。好吧,它们肯定是一种糟糕的进程间机制:-)为什么有人会这么想!难道现在的开发人员还没有基本掌握操作系统为他们做了什么吗!内存管理器是在执行malloc()或now之类的操作时为您动态分配内存的工具。这只与库地址空间问题有切面关系,因为您可以在同一个.c或.cpp源文件中使用不同的管理器,而不是在不同的库中使用不同的管理器。@Neil。我认为作者指的是每个DLL静态链接到运行库时的问题。这导致每个DLL基本上都进行自己的内存管理(因此一个DLL无法释放另一个DLL分配的内存)。这个问题早就解决了,不过在运行库中使用了共享DLL。@martin我只是想消除一个可能的麻烦。基本问题是关于内存空间,而不是特定语言的内存分配。是的,Neil,如果没有共享库,这个问题可能会发生,但它们有更多的潜力。马丁,问题是可以解决的,但这和解决的不一样。它们可以链接到不同的版本,也可以链接到不同供应商的运行时。库使用者可能使用完全不同的语言,无法调用
delete
。最后,尼尔,这可能超出了最初的问题,但我认为在这个上下文中仍然值得一提,因为记住拥有相同的地址空间并不意味着拥有相同的内存池。我非常怀疑,在同一内存空间中,最终可以实现与不同的和不兼容的C++库链接的库是一种符合性的实现。实施……这个问题已经解决了。这对于windows上的旧开发是正确的,随着现代开发,它不再是有效的问题。请确保将所有DLL链接到运行时的共享版本。谢谢,我不知道已经更改了。我最近遇到的问题很可能是静态运行库的两个实例,它们在可执行文件和DLL之间不共享。这超出了C++的范围(您正在考虑在汇编级别上进行调理)。有很好的理由不这样做(具体)