【问题标题】:Raw pointer to shared_ptr bug指向 shared_ptr 错误的原始指针
【发布时间】:2021-11-05 01:44:32
【问题描述】:

我正在开发一个图像处理应用程序。

总之,我有一个存储图像数据的字节缓冲区,所以我可以使用这个数组在 wx 小部件和 OpenCV 中轻松处理图像。我计划将此字节缓冲区存储在 shared_ptr 中,因为它将在执行过程中用于同一类的其他实例。

使用原始指针它可以正常工作,但是每当我尝试使用 shared_ptr 时,只要将此指针传递给函数,就会出现分段错误。

如何在没有分段错误的情况下将其传递给该函数?这个崩溃对我来说没有意义

问题在这里

_dataSize = (size_t)len;
_originalData = std::make_shared<void*>(malloc(_dataSize));
if ( file.Read(_originalData.get(), _dataSize) != len )

在上面代码的最后一行,我试图将 _original 数据指针传递给读取函数

这是full code,在上面的部分中,我只是写了错误正在发生的那一行。在完整的代码中,错误位于第 18 行的 src/Img.cpp 文件中

谢谢

【问题讨论】:

  • 你没有在传递给make_shared的参数中进行分配。见stackoverflow.com/questions/20895648/…
  • 如果你传递malloc生成的指针,你必须传递一个调用free的删除器。
  • 您真的想要共享void* 的所有权,还是想要共享void* 指向的对象的所有权?
  • make_shared&lt;T&gt;(arguments)arguments 创建一个T 类型的新共享对象。 shared_ptr&lt;T&gt;(p) 拥有p 指向的对象的所有权。
  • 在这种情况下,我希望在运行时共享所有权,它将将此缓冲区复制到其他 Img 对象

标签: c++ c++17 shared-ptr smart-pointers


【解决方案1】:

_originalData.get()void**,而不是 void*

要共享该分配的所有权,您需要std::shared_ptr&lt;void&gt;,而不是std::shared_ptr&lt;void*&gt;。您还需要设置释放函数,因为它是指向 delete 的未定义行为,它是 malloced 的指针。

_originalData = std::shared_ptr<void>{ malloc(len), free }; // _originalData is a `std::shared_ptr<void>
if ( file.Read(_originalData.get(), len) != len )

或者,从 C++20 开始,您可以使用 std::shared_ptr&lt;char[]&gt;,而根本不使用 malloc

_originalData = std::make_shared_for_overwrite<char[]>{ len }; // _originalData is a `std::shared_ptr<char[]>
if ( file.Read(*_originalData, len) != len ) // implicit conversion of char* to void*

【讨论】:

  • 不错。我会尝试你的答案并在这里给出反馈。非常感谢
  • 在这个项目中,由于我无法决定的原因,我不能使用 C++20。但是您定义删除函数的解决方案有效,我之前确实尝试过类似的方法,但是在 shared_ptr 的声明中,这似乎是不允许的。顺便说一句,我实施了您的建议并且效果很好,并且我还保存了 C++20 代码以便在可能的情况下更好地使用它。再次非常感谢您
  • std::make_shared_for_overwrite - 不知道,谢谢:)
【解决方案2】:

看看what make_shared does

它将尝试构造一个 T 类型的对象,将您提供的参数发送给构造函数。

在您的代码中,它将尝试创建一个新的 void* 对象(将mallocs retunr 指针作为参数传递),我相信您不想这样做。

如果您使用shared_pointer 的对象构造函数描述为here on 3-7

构造一个shared_ptr,将ptr作为指向托管对象的指针。

我认为你想做的事

【讨论】:

  • 我认为 Caleth 的答案是唯一的,只是在这里留下了参考:)
  • 非常感谢您的帮助。我稍后再试。
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
相关资源
最近更新 更多