DAG析构函数中的错误

冗长

我有一个Dag类(有向无环图),其中包含指向类Node对象的原始指针的向量。该向量被调用m_roots,并由没有后代的所有节点组成。(但是它们最多可以有两个父对象)。Node对象形成各种二叉树。节点的成员属性为:

int m_indiv;
Node * m_dad;
Node * m_mom;
std::vector<Node * > m_offsprings;
int m_generat;

因此,尽管结构是非循环的,但我在两个方向上都有指针。Dag构造函数将启动一个重复操作,该重复操作将根据地图中包含的数据创建节点。这是循环部分:

void Node::recNode(const map<int, pair<int, int> > &mapPed, map<int, Node * > &mapDup, const vector <int> &sampleListe, vector<Node * > &sample)
{

    if (find (sampleListe.begin(), sampleListe.end(), this->m_indiv) != sampleListe.end()) {
        sample.push_back(this);
    }
    pair<int, int> parents;


    if (parents.first!=0) { //0 is a reserved integer for missing data, pointer stay to NULL (nullptr)
        if (mapDup.find(parents.first) == mapDup.end() || !(mapDup[parents.first])) {
            m_dad=new Node(parents.first);
            if (mapDup.find(parents.first) != mapDup.end()) { 
                mapDup[parents.first]=m_dad;
            }
            m_dad->recNode(mapPed, mapDup, sampleListe, sample);
        }
        else {
            m_dad=mapDup[parents.first];
        }
        m_dad->m_offsprings.push_back(this); //add the pointer to this node in the dads list of offspring
    }

    //do the same for the second parent
    if (parents.second!=0) {
        if (mapDup.find(parents.second) == mapDup.end() || !(mapDup[parents.second]) ) {
            m_mom=new Node(parents.second);
            if (mapDup.find(parents.second) != mapDup.end()) {
                mapDup[parents.second]=m_mom;
            }
        m_mom->recNode(mapPed, mapDup, sampleListe, sample);
        }
        else {
            m_mom=mapDup[parents.second];
        }
        m_mom->m_offsprings.push_back(this); //add the pointer to this node in the moms list of offspring
    }

}

我的Dag析构函数启动递归销毁:

Dag::~Dag()
{
    for (int i(0); i<m_roots.size();++i) {
        delete m_roots[i];
    }
}

Node析构函数应该进行实际的销毁:

Node::~Node()        

{
    if(m_dad) {
        Node* dummyD=m_dad;
        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;
            }
        }
        delete dummyD;
    }
    if(m_mom) {
        Node* dummyM=m_mom;
        for (int i(0); i<m_mom->m_offsprings.size();++i) {
            if (m_mom->m_offsprings[i]) {
                m_mom->m_offsprings[i]->m_mom=nullptr;
            }
        }
        delete dummyM;
    }

}

由于某些原因,此方法不起作用:我遇到了段错误。相应的Valgrind错误为:

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) {

在第一次迭代之后。(在第一次调用〜Dag()和第一次调用〜Node()期间)。从for循环中中断的i刚从0更改为1。事实上,它在早期中断的事实使得它不太可能是Dag中循环的问题...我也有一个'__in_charg'函数参数,它是<optimized out>(尽管-O0)。我不确定这是什么意思,但似乎Node* dummyD=m_dad;还没读...

我正在寻找它不起作用的原因,逻辑上的缺陷...我知道可以shared_ptr为父母和weak_ptr后代使用。

注意:术语父母/后代在某些领域是特定的。在这里,我用它来表达“生物学”的感觉:每个人只有一个妈妈和一个爸爸,但可以有0到n个后代。

焦虑的

Node::~Node()功能上,似乎this是其中之一m_offsprings因此,在第一次迭代之后

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;
    }
}

this->m_dad成为nullptr之后,您尝试在中取消引用它m_dad->m_offsprings.size()

为了解决这个问题,检查当前的那个地址m_dadm_offspring不等于this(与相同m_mom)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章