C++ DAG析构函数中的错误

C++ DAG析构函数中的错误,c++,destructor,directed-acyclic-graphs,C++,Destructor,Directed Acyclic Graphs,我有一个Dag类(有向无环图),它包含指向类节点对象的原始指针向量。该向量称为m_根,由所有没有子节点的节点组成。(但它们最多可以有两个父节点)节点对象形成各种二叉树。 节点的成员属性包括: int m_indiv; Node * m_dad; Node * m_mom; std::vector<Node * > m_offsprings; int m_generat; 每行调试一行时,它在以下行中断: for (int i; i<m_dad->m_offsprings

我有一个Dag类(有向无环图),它包含指向类节点对象的原始指针向量。该向量称为
m_根
,由所有没有子节点的节点组成。(但它们最多可以有两个父节点)节点对象形成各种二叉树。 节点的成员属性包括:

int m_indiv;
Node * m_dad;
Node * m_mom;
std::vector<Node * > m_offsprings;
int m_generat;
每行调试一行时,它在以下行中断:

for (int i; i<m_dad->m_offsprings.size();++i) {
for(int i;im_offsprings.size();++i){
在第一次迭代之后。(在第一次调用~Dag()和第一次调用~Node()期间)。for循环中断处的i从0更改为1。 事实上,它很早就打破了这一点,这不太可能是Dag中的周期问题。。。 我还有一个“\u in\u charg”函数参数,它是
(尽管是-O0)。我不确定它的意思,但似乎
节点*dummyD=m\u dad;
没有被读取

我正在寻找它不起作用的原因,逻辑上的缺陷……我知道,对于父母来说,可以使用
共享ptr
,对于后代来说,可以使用
弱ptr


注意:父代/子代的命名有点特定于领域。这里我在“生物学”中使用它sens:每个人只有一个妈妈和一个爸爸,但可以有0到n个后代。

不是一个直接的解决方案,但我想更有用的是:如果可能的话,使用智能指针完全消除所有提到的问题

Node
{
    int m_indiv;
    Node * m_dad;
    Node * m_mom;
    std::vector<std::shared_ptr<Node> > m_offsprings;
    int m_generat;
}
节点
{
印度国际大学;
Node*m_-dad;
Node*m_mom;
std::向量m_子代;
int m_generat;
}

不,如果一个节点被析构函数(--并且它是最后一个指向子代的节点),所有子代析构函数都会自动被递归调用。因此,无需编写更多容易出错的代码。

m_根[0]和m_根[1]共享同一个dad。 当你删除节点m_根[0]时,它的爸爸妈妈以及他们的整个“家族”都会被删除。因此,m_根[1]会变成一个孤儿。

节点::~Node()
函数中,似乎
这是
m_子代之一

for (int i(0); i<m_dad->m_offsprings.size();++i) {
    if (m_dad->m_offsprings[i]) {
        m_dad->m_offsprings[i]->m_dad=nullptr;
    }
}
for(int i(0);im_offsprings.size();++i){
如果(妈妈爸爸->妈妈的后代[i]){
m_-dad->m_子代[i]->m_-dad=nullptr;
}
}
this->mu dad
变为
nullptr
。之后,您将尝试在
mu dad->mu offsprings.size()中取消对它的引用


要解决此问题,请检查当前
MU dad
MU后代的
地址是否不等于
this
(与
MU mom
相同)

请提供一个。你从来没有初始化过
i
-你应该这样做。可能问题本身不在析构函数代码中,而是在其他地方:
m_根
不正确或图形不是真正的非循环。这就是为什么@m.s.点很重要。
m_妈妈->后代
-他们是你的兄弟姐妹。暂时忽略代码。你是什么甚至试着去做?!“Dag”中的根节点到底是什么?最小的孩子还是最年长的父母?@MSalters m_mom->子节点是我和我的兄弟姐妹。根节点是所有没有子节点的节点。所以他们在某种意义上是最小的子节点。我只想一次又一次地破坏所有节点。我帖子的最后一行是解决了这个问题,但感谢您的建议。为什么
m_根[1]
是孤立的问题?在删除dad之前,从
m_根[1]
指向dad的指针应设置为
nullptr
,并且在删除
m_根[1]
if(m_-dad)
将为false,并将去照顾母亲。这是错误的吗?此外,如果这是问题所在,则代码将在第二次迭代~Dag()后中断.点,但从未达到。或?@Prolix:回答你的第二个评论,不,这正是它将中断的地方。由于m_dad已被删除,你无法再访问其m_后代向量。你能在两个节点之间添加父子关系的代码吗?我发布了创建Dag关系的代码。谢谢你的帮助!你的回答不完全正确,但你的评论是正确的。+1这很有意义!我在删除部分使用了虚拟ptr,但我没有想到for循环!非常感谢!我现在无法测试它,但是如果我在for循环中使用
dummyD->m_子循环
指针而不是
m_-dad->m_offsprings
它也应该修复它,不是吗?
InvalidRead                                     Invalid read of size 8
                                                Call stack:
/usr/include/c++/4.8/bits/stl_vector.h  646     0x411734: Node::~Node()
~/Dag.cpp                               138     0x409E98: Dag::~Dag()
~/main.cpp                              114     0x41062B: main
            Address 0x18 is not stack'd, malloc'd or (recently) free'd
for (int i; i<m_dad->m_offsprings.size();++i) {
Node
{
    int m_indiv;
    Node * m_dad;
    Node * m_mom;
    std::vector<std::shared_ptr<Node> > m_offsprings;
    int m_generat;
}
for (int i(0); i<m_dad->m_offsprings.size();++i) {
    if (m_dad->m_offsprings[i]) {
        m_dad->m_offsprings[i]->m_dad=nullptr;
    }
}