我一直在函数解析系统中处理一些代码。它以树状结构来实现。目前,它只跟踪孩子,但我也想添加父母的信息。具体来说,我正在尝试添加一个指向父母的指针列表。但是,当我删除父母时,我需要从孩子中删除指针。当我尝试执行此操作时,会出现段错误。
这是设置_subnodes列表的构造函数。
EBUnaryTermNode(EBTermNode * subnode) : _subnode(subnode){
_subnode->_parents.push_back(this);
};
这里是析构函数,它调用擦除指向父对象的指针的函数。
virtual ~EBUnaryTermNode() {
_subnode->eraseParent(this);
if(_subnode->_parents.size() == 0 && _subnode->_holders.size() == 0)
delete _subnode;
};
这是删除指向父对象的指针的函数。
void eraseParent(EBTermNode * victim)
{
std::list<EBTermNode *>::iterator it;
for(it = _parents.begin(); it != _parents.end(); ++it)
if(*it == victim)
{
std::cout << victim << std::endl;
_parents.erase(it);
break;
}
}
EBUnaryTermNode类继承自此处定义的基类EBTermNode。
class EBTermNode
{
public:
virtual ~EBTermNode(){};
virtual EBTermNode * clone() const = 0;
virtual std::string stringify() const = 0;
virtual unsigned int substitute(const EBSubstitutionRuleList & /*rule*/) { return 0; }
virtual int precedence() const = 0;
friend std::ostream & operator<<(std::ostream & os, const EBTermNode & node)
{
return os << node.stringify();
}
void eraseParent(EBTermNode * victim)
{
std::list<EBTermNode *>::iterator it;
for(it = _parents.begin(); it != _parents.end(); ++it)
if(*it == victim)
{
std::cout << victim << std::endl;
std::cout << *it << std::endl;
_parents.erase(it);
break;
}
}
std::list<EBTermNode *> _parents;
std::list<EBTerm *> _holders;
};
在遇到段错误之前,它似乎可以工作一段时间(大约是cout语句的25倍)。
当我从调试器浏览堆栈时,得到以下信息:
Thread 1 "phase_field-dbg" received signal SIGSEGV, Segmentation fault.
0x00007fffe9adbf8d in __gnu_debug::_Safe_iterator_base::_M_singular (this=0x421010)
at ../../../../../gcc-8.3.0/libstdc++-v3/src/c++11/debug.cc:403
403 ../../../../../gcc-8.3.0/libstdc++-v3/src/c++11/debug.cc: No such file or directory.
(gdb) up
#1 0x00007ffff77c14a2 in __gnu_debug::_Safe_sequence<std::__debug::list<ExpressionBuilder::EBTermNode*, std::allocator<ExpressionBuilder::EBTermNode*> > >::_M_invalidate_if<__gnu_debug::_Equal_to<std::__cxx1998::_List_const_iterator<ExpressionBuilder::EBTermNode*> > >
(this=0xa4e598, __pred=...)
at /opt/moose/gcc-8.3.0/include/c++/8.3.0/debug/safe_sequence.tcc:48
48 if (!__victim->_M_singular() && __pred(__victim->base()))
(gdb)
#2 0x00007ffff77bda03 in std::__debug::list<ExpressionBuilder::EBTermNode*, std::allocator<ExpressionBuilder::EBTermNode*> >::_M_erase (this=0xa4e598, __position=...)
at /opt/moose/gcc-8.3.0/include/c++/8.3.0/debug/list:490
490 this->_M_invalidate_if(_Equal(__position));
(gdb)
#3 0x00007ffff77b918c in std::__debug::list<ExpressionBuilder::EBTermNode*, std::allocator<ExpressionBuilder::EBTermNode*> >::erase (this=0xa4e598, __position=...)
at /opt/moose/gcc-8.3.0/include/c++/8.3.0/debug/list:503
503 return iterator(_M_erase(__position.base()), this);
(gdb)
#4 0x00007ffff77b231c in ExpressionBuilder::EBTermNode::eraseParent (this=0xa4e590,
victim=0xa4e7a0)
at /home/jason/Research/GBResearch/projects/moose/modules/phase_field/build/header_symlinks/ExpressionBuilder.h:95
95 _parents.erase(it);
(gdb)
#5 0x00007ffff77b27ab in ExpressionBuilder::EBUnaryTermNode::~EBUnaryTermNode (
this=0xa4e7a0, __in_chrg=<optimized out>)
at /home/jason/Research/GBResearch/projects/moose/modules/phase_field/build/header_symlinks/ExpressionBuilder.h:155
155 _subnode->eraseParent(this);
非常感谢您的帮助。