【问题标题】:Reference to shared pointer becomes corrupted对共享指针的引用已损坏
【发布时间】:2019-01-16 22:34:04
【问题描述】:

即使 shared_ptr 仍然拥有,对共享指针的引用也会损坏。

我在应用程序中有类似以下代码 sn-p 的内容,并且在尝试使用对类对象内的 shared_ptr 的引用时,不断获得对指针的悬空引用或其他一些损坏。下面的基准在使用 gcc 5.4.0 的 RHEL7 上也表现出同样的问题。 clang 4.0.1 也会发生这种情况。我已经验证 shared_ptr 在系统退出之前从未真正破坏指向的对象。

在 A 中存储 shared_ptr 时,一切正常。

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

using namespace std;

class Int
{
  public:
    Int() : Int(0) { }
    Int(int v) : _val(v) { }
    int val() const { return _val; }
    ~Int() { }

  private:
    int _val;
};

typedef shared_ptr<Int> IntPtr;

class A
{
  public:
    IntPtr &intPtr;
    A() = delete;
    A(IntPtr &int_ptr) : intPtr(int_ptr)
    {
        cout << "A()" << endl;
        cout << intPtr.use_count() << endl;
        cout << intPtr->val() << endl;
    }
};

class B
{
  public:
    B(A *a) : _a(a) { }
    B() = delete;
    A *_a;
};

vector<IntPtr> intPtrs;

A* makeNew()
{
    IntPtr int_ptr = make_shared<Int>(44883);
    intPtrs.push_back(int_ptr);
    cout << "makeNew()" << endl;
    cout << intPtrs.back().use_count() << endl;
    cout << intPtrs.back()->val() << endl;
    A *a = new A(int_ptr);

    return a;
}

void checkB(B *b)
{
    A *a = b->_a;
    assert(a);
    cout << "checkB()" << endl;
    cout << a->intPtr.use_count() << endl;
    cout << a->intPtr->val() << endl;
}

int main(int argc, char *argv[])
{
    B *b = new B(makeNew());
    checkB(b);
    cout << "main()" << endl;
    A *a = b->_a;
    cout << a->intPtr.use_count() << endl;
    cout << a->intPtr->val() << endl;

    cout << "intPtrs size: " << intPtrs.size() << endl;

    for (const auto &int_ptr : intPtrs) {
        cout << int_ptr.use_count() << endl;
        cout << int_ptr->val() << endl;
    }

    return 0;
}

makeNew() 2 44883 一种() 2 44883 检查B() -324888 -610139856 主要的() -610139968 -1066293104 intPtrs 大小:1 1 44883

上面是生成的输出,可以在 checkB() 中看到,或者在检查 main() 中新创建的对象时,我得到了垃圾。

因为向量是 IntPtr 的所有者,并且具有持续到程序结束的生命周期,所以我希望 A 中的引用没问题。

【问题讨论】:

  • 您是否尝试过使用asan 编译代码和/或使用valgrind 运行它?
  • 您存储了对本地int_ptr 的引用,那么您期望什么? Because the vector is the owner of the IntPtr and has a lifetime that lasts until the program ends, I would expect the reference in A to be fine. 向量拥有它自己的 shared_ptr 实例,这不会让其他实例保持活动状态。

标签: c++11 shared-ptr


【解决方案1】:

makeNew 返回一个指向 A 的指针,其中包含对 IntPtr 的引用;但是这个IntPtr 已经被销毁了,它是makeNew 中的一个局部变量。所以引用失效了。

我假设 shared_ptr 引用计数在您将 ptr 分配给另一个变量时有效,但在您保留对它的引用时无效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 2020-09-26
    • 2015-08-05
    相关资源
    最近更新 更多