【问题标题】:shared_ptr not returned correctlyshared_ptr 未正确返回
【发布时间】:2019-01-27 21:06:23
【问题描述】:

我有以下代码:

#include <memory>
#include <vector>
#include <iostream>

class MarchingEvent
{
public:
    MarchingEvent() {}
};

class DerivedEvent : public MarchingEvent
{
public:
    DerivedEvent() {}
};

std::shared_ptr<MarchingEvent> function1()
{
    return std::make_shared<DerivedEvent>();
}

std::shared_ptr<MarchingEvent> function2()
{
    std::shared_ptr<MarchingEvent> event = function1();
    if (event)
        return event; // This line crashes...

    return std::shared_ptr<MarchingEvent>();
}

int main()
{
    std::shared_ptr<MarchingEvent> event = function2();

    std::cout << "hello";

    return 0;
}

运行 function2() 时,我在 return event; 行发生崩溃,该崩溃是 SIGABRT,我可以追溯到 std 文件 shared_ptr_base。 h 在以下情况下:

  // Counted ptr with no deleter or allocator support
  template<typename _Ptr, _Lock_policy _Lp>
    class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
    {
    public:
      explicit
      _Sp_counted_ptr(_Ptr __p)
      : _M_ptr(__p) { }

      virtual void
      _M_dispose() noexcept
      { delete _M_ptr; }

你知道我做错了什么吗?

【问题讨论】:

  • 将 DerivedEvent 的 dtor 设为 public 和 MarchingEvent 虚拟,看看是否有帮助。
  • 也许你在之前的代码中损坏了堆,然后崩溃发生了(这对于堆损坏来说是正常的)。
  • @cplusplusrat 从 make_shared 分配给 shared_ptr 时不需要虚拟析构函数。删除器是类型擦除的。
  • @cplusplusrat:这没有帮助

标签: c++ c++11 stl std


【解决方案1】:

创建一个简单的 MCVE。它将证明:

a) 您的实现存在错误(极不可能),或者

b)您在其他地方有错误或 UB(极有可能)

示例 MCVE:

#include <memory>
#include <vector>
#include <iostream>

class MarchingEvent
{
};

class DerivedEvent : public MarchingEvent
{
};

std::shared_ptr<MarchingEvent> function1()
{
    return std::make_shared<DerivedEvent>();
}

std::shared_ptr<MarchingEvent> function2()
{
    std::shared_ptr<MarchingEvent> event = function1();
    if (event)
        return event; // This line crashes...

    return std::shared_ptr<MarchingEvent>();
}



int main()
{
    for (int i = 0 ; i < 10 ; ++i)
    {
        std::vector<std::shared_ptr<MarchingEvent>> v(10000);
        for(int j = 0 ; j < 10000 ; ++j)
        {
            v[j] = function2();
        }
    }
    std::cout << "done\n";
}

我的主张的有力证据:http://coliru.stacked-crooked.com/a/1b554b334212a0ea

【讨论】:

    猜你喜欢
    • 2016-09-11
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-01
    相关资源
    最近更新 更多