【问题标题】:C++ using std::vector across boundaries [duplicate]C ++使用std :: vector跨越边界[重复]
【发布时间】:2015-06-08 15:20:15
【问题描述】:

假设 EXE 和 DLL 使用相同的编译器和 STL 版本。如果我在我的 EXE 中使用 std::vector 并使用 reserve 来保留内存。然后我将它作为对 DLL 的引用传递。

我在 DLL 中执行 push_back 以将元素添加到我的向量中。如果我没有超出实际容量,新元素的内存是在 DLL 中还是在 EXE 中分配的?

【问题讨论】:

标签: c++ c++11 dll vector stl


【解决方案1】:

This is generally a bad idea.

当您调用push_back 时,可以为您添加到向量中的任何对象制作副本。无法保证该对象的大小(除其他外)与通过std::vector::reserve 在.exe 中保留的大小相同。这两个二进制文件可能是使用不同版本的 STL 编译的。

【讨论】:

  • 好的,我明白了,但假设向量容量足够大并且满足所有关于二进制文件的限制(编译器、库、异常设置……)。这样做可以吗(从记忆的角度来看)?也就是说,如果DLL在此之后被释放,数据是否仍然存在并且可以访问?
  • 假设一切都完美无缺,当然。然而,跨 DLL 边界传递东西仍然是一个坏主意。您应该寻找不同的解决方案来共享您需要的信息。 (即,在 DLL 中分配向量并返回对 EXE 的引用)。
【解决方案2】:

都不是。

分配在进程的虚拟内存空间中,其代码是.exe.dll的组合。

【讨论】:

  • 嗯,不。 DLL 通常使用不同的内存分配器,并且您不应跨 DLL 边界传递资源。参考Potential Errors Passing CRT Objects Across DLL Boundaries
  • 如果 EXE 和 DLL 都使用相同的 VC++ 编译器和设置构建并动态链接到相同的 CRT 风格(我知道这是非常受限制的),那么我相信 Lightness 的答案是正确的。如果您构建一个测试 EXE 和 DLL 并从每个中调用 _get_heap_handle(),您将获得 same 返回的句柄(至少,这是我在测试中得到的)。我在答案中写了这个,但不幸的是这个问题(IMO错误地)关闭了,所以我在这里写评论。
  • @Mr.C64:即使在您命名的约束下,这个答案仍然是错误的:内存永远不会在虚拟地址空间中分配。它在堆中分配,其内存映射到所述地址空间。堆由相应的模块拥有。这种区别虽然很重要,但却完全没有出现在答案中。
猜你喜欢
  • 2021-04-16
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2013-02-26
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多