【问题标题】:Debug assertion failure - C++, using smart pointers调试断言失败 - C++,使用智能指针
【发布时间】:2021-12-07 14:47:35
【问题描述】:

我一直在尝试调试它一段时间,但没有任何运气。我希望在这里得到一些帮助。抱歉,如果我的问题不相关或其他什么,我是新人。

所以基本上我所拥有的是:

#include <iostream>

template<typename T> class Node {
    using NodePtr = std::shared_ptr<Node<T>>;
private:
    Node() {}
    T value{};
    NodePtr parent;
    NodePtr child;
public:
    Node(const T& value) : value{ value } {}
    Node(const T& value, NodePtr child) : Node(value)
    {
        this->child = child;
        if (child != NULL)
        {
            //problem here?  
            child->parent = NodePtr(this);
       
             /*The equivalent in C# works perfectly fine:*/
            
                /*this.child = child;
                if(child != null) {
                    child.parent = this;
                }*/
            

        }
    }

    const T& Value()    const { return value; }
    T& ValueRef()       const { return value; }
    NodePtr Parent()     const { return parent; }
    NodePtr Child()     const { return child; }
};
template<typename T> std::ostream& operator<<(std::ostream& stream, const Node<T>& node) {
    stream << "{" << node.Value() << "}";
    return stream;
}
int main()
{
    Node<int> n{ 5, std::make_shared<Node<int>>(3) };
    std::cout << n;
}

我可以在不使用智能指针的情况下轻松实现这一点,但我正在尝试学习它们,所以就是这样。

失败的断言:“is_block_type_valid(header->_block_use)”

Image of the assertion error

任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 当你看到这样的断言时,实际的错误就在源文件下面。在这种情况下,错误/失败的断言是“is_block_type_valid(header->_block_use)”,如果您具体搜索一下,这可能会对您有所帮助。
  • 通过有两个不相关的共享指针指向Node,您似乎获得了双重释放。您需要使用std::enable_shared_from_this
  • 我很抱歉@FredLarson,我一直在尝试实现它,但没有运气。你能写一个例子来说明如何做吗?

标签: c++ pointers data-structures smart-pointers


【解决方案1】:

有几个问题。首先,如果你想从中获取一个shared_ptr,你必须继承自std::enable_shared_from_this:

template<typename T> class Node : std::enable_shared_from_this<Node<T>> {
    // ...

主要问题是有一个 shared_ptr 引用了一个 shared_ptr(父级到子级,反之亦然)。但是,shared_ptr 仅被引用计数。看看下面的程序:

#include <iostream>
#include <memory>
struct A;

struct B{
    std::shared_ptr<A> sp;
    ~B(){ std::cout << "B destroyed\n"; }
};
struct A{
    std::shared_ptr<B> sp;
    ~A(){ std::cout << "A destroyed\n"; }
};

int main(){
    std::shared_ptr<B> b{};
    std::shared_ptr<A> a {b->sp};
    b = a->sp;
}

输出为空白! Here 是上述程序的链接。

要修复,请做两件事:第一,将child-&gt;parent = NodePtr(this); 更改为以下内容:

child->parent = this->weak_from_this();

另外,将parent 的类型更改为std::weak_ptr&lt;Node&lt;T&gt;&gt;

std::weak_ptr 用于处理此类问题。它不会影响std::shared_ptr 的引用计数。更多信息,请转到here

附:关于 is_block_type 的错误是由 shared_ptr 引起的,可能是因为您试图从原始 ptr 中获取 shared_ptr。阅读有关 std::shared_ptr here 的更多信息。

【讨论】:

    猜你喜欢
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多