c++ 使用标准::共享指针时的_CrtIsValidHeapPointer(块)

wkyowqbh  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(174)

我试图在一个类函数中创建和使用一个std::shared_ptr,该函数的构造函数接受一个std::shared_ptr私有数据成员(属于同一个类)和另一个std::shared_ptr,该std::shared_ptr是用指向类对象的原始指针(this)创建的。
每当我调用创建std::shared_ptrfoo)的函数时,我都会得到一个_CrtIsValidHeapPointer(block)Assert。我假设它与删除shared_ptr的方式有关,但我似乎找不到答案,我在互联网上搜索了所有的地方。也许我没有完全理解shared_ptr是如何工作的。
使用this指针或预先存在的shared_ptr数据成员创建shared_ptr是否不可接受?

class Containing_Class;

class Some_Class
{
};

class Set_Value_Command
{
public: 
    Set_Value_Command(std::shared_ptr<Some_Class> ptr1, std::shared_ptr<Containing_Class> ptr2)
        : _ptr1(ptr1), _ptr2(ptr2) 
    {}
private:
    std::shared_ptr<Some_Class> _ptr1;
    std::shared_ptr<Containing_Class> _ptr2;
};

class Containing_Class
{
public:
    Containing_Class(std::shared_ptr<Some_Class> psc)
        : _psc(psc)
    {}

    void foo()
    {
        std::shared_ptr<Set_Value_Command> command = std::make_shared<Set_Value_Command>(_psc, std::shared_ptr<Containing_Class>(this));
    }
private:
    std::shared_ptr<Some_Class> _psc;
};

下面是main()函数。当foo()被调用时,Assert发生:

int main()
{
    std::shared_ptr<Some_Class> some_class = std::make_shared<Some_Class>();
    Containing_Class cc(some_class);
    cc.foo();
}
qq24tv8q

qq24tv8q1#

使用this指针创建shared_ptr是否不可接受
不是单独的,不。在你的例子中这样做是非常糟糕的。你的Containing_Class对象是在main()的本地堆栈帧的自动内存中创建的。因此当main()退出时,当它超出范围时将被自动销毁。但是在Containing_Class对象内部从this创建shared_ptr会将this的所有权分配给shared_ptr,然后当不再有对thisshared_ptr引用时delete将尝试thisdelete对不是以new创建的对象进行开始是 * 未定义行为 *,这就是为什么您会因为一个关于无效堆指针的错误而崩溃。
为了允许shared_ptr引用thisContaining_Class需要从std::enable_shared_from_this派生,并且this必须指向一个动态创建并由shared_ptr拥有的对象。只有这样,Containing_Class才能调用其继承的shared_from_this()方法来获得shared_ptr
例如:

class Containing_Class;

class Some_Class
{
};

class Set_Value_Command
{
public: 
    Set_Value_Command(std::shared_ptr<Some_Class> ptr1, std::shared_ptr<Containing_Class> ptr2)
        : _ptr1(ptr1), _ptr2(ptr2) 
    {}
private:
    std::shared_ptr<Some_Class> _ptr1;
    std::shared_ptr<Containing_Class> _ptr2;
};

class Containing_Class : public std::enable_shared_from_this<Containing_Class>
{
public:
    Containing_Class(std::shared_ptr<Some_Class> psc)
        : _psc(psc)
    {}

    void foo()
    {
        std::shared_ptr<Set_Value_Command> command = std::make_shared<Set_Value_Command>(_psc, shared_from_this());
    }

private:
    std::shared_ptr<Some_Class> _psc;
};
int main()
{
    auto some_class = std::make_shared<Some_Class>();
    auto cc = std::make_shared<Containing_Class>(some_class);
    cc->foo();
}
3pvhb19x

3pvhb19x2#

有了密码

std::shared_ptr<Containing_Class>(this)

引入第二个*this所有者,即command是控制cc寿命的共享指针的所有者。这是第一个问题。还有另一个问题,接下来的问题是command指向堆栈对象。
通常*this由某人所有,将所有权传递给另一个所有者是行不通的。
由于缺乏代码目标,当前代码无法修复。

相关问题