【问题标题】:Forcing the copy constructor instead of the move constructor强制复制构造函数而不是移动构造函数
【发布时间】:2015-08-24 12:26:06
【问题描述】:

我的程序崩溃然后一个字符串对象被删除,我想是因为我使用为 VS 2010 编译的 oracle 库,而我使用的是 VS 2015。这是它崩溃的行:

string f1 = cObj.getString(MetaData::ATTR_NAME);

我得到一个正常的字符串,我可以使用它,但是当它超出范围时,它会在尝试解除分配时崩溃。 现在,在阅读有关使用旧版本 DLL 的信息时,我读到如果分配发生在该库内部,我们应该始终将内存释放留给 DLL。我想这里发生的是调用了移动构造函数,所以最后它尝试解除分配由 oracle dll 分配的内存的字符串。

所以我的问题是,有没有办法在这种情况下显式调用字符串的复制构造函数?

【问题讨论】:

  • CRT 可能不匹配
  • 明确使用赋值是否有效?如果不是,您的问题可能出在其他地方。
  • 您可以使用 string f1 = const_cast<const string &>(cObj.getString(MetaData::ATTR_NAME); 强制复制构造函数,但我怀疑这可以解决您的版本不匹配问题。
  • @nwp,奇怪,现在 deallocate get 在你的行之后被调用并且程序崩溃了,所以这意味着有临时对象被破坏 - 这意味着问题可能不在移动构造函数中?所有这些函数调用都不会发生这种情况,所以很难理解这些 CRT 的东西......
  • 我会尝试找到 VS2015 版本的 dll。如果不可用,您可以安装 VS2010 并在 VS2015 中选择 VS2010 套件。如果这也不可行,请在 VS2010 中编写一个包装器,通过套接字或管道公开 DLL 函数。一些不好的可能性是不使用返回具有动态内存的对象的函数或泄漏它们的内存。

标签: c++ copy-constructor move-constructor


【解决方案1】:

可执行文件和链接的 DLL 必须是二进制兼容的。通常,它们需要由相同的编译器生成。有时不同的编译器版本使用相同的 ABI 并且它会继续工作,但在你的情况下不是。

ABI 定义了如何分配和释放内存,DLL 和可执行文件对其工作方式有不同的假设,因此会崩溃。

有不同的方法来解决这个问题,从好到坏排序:

  1. 通过升级 DLL 使版本一致
  2. 通过降级可执行文件使版本一致
  3. 以正确的版本编写包装器,以通过套接字或管道公开功能
  4. 不要使用返回动态内存对象的函数
  5. 泄露内存

如果是 Visual Studio,您可以安装旧版和新版 Visual Studio,在新版本中转到 Solution ExplorerConfiguration PropertiesGeneralPlatform Toolsetselect the old platform

请注意,降级目标平台会使新功能不可用。

【讨论】:

  • 感谢您的精彩回答 :)
猜你喜欢
  • 1970-01-01
  • 2020-08-13
  • 2022-11-21
  • 2021-12-25
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多