我有一个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_dad
的m_offspring
不等于this
。(与相同m_mom
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句