为什么这些访问方式会导致内存泄漏呢?
Why do these visit methods cause memory leaks?
我正在开发一个使用访问者模式的中型 C++ 框架。
对实现此框架的程序进行的 valgrind 测试报告了一些内存泄漏,这些内存泄漏可以追溯到其中一位访客,即 copyCreator
。
template<typename copyNodeType>
struct copyCreator {
copyCreator {}
copyCreator(node * firstVisit) {
firstVisit->accept(*this);
}
~copyCreator() {
copy.reset();
for(auto ptr : openList) {
delete ptr;
}
}
std::unique_ptr<copyNodeType> copy = 0;
vector<nonterminalNode *> openList;
// push to tree
template<typename nodeType>
void push(nodeType * ptr) {
if (copy) {
// if root is set, append to tree
openList.back()->add_child(ptr);
}
else {
auto temp = dynamic_cast<copyNodeType *>(ptr);
if(temp) {
copy = std::unique_ptr<copyNodeType>(temp);
}
}
}
// ...
void visit(struct someNonterminalNode & nod) {
auto next = new someNonterminalNode(); //This is leaked
push(next);
openList.push_back(next);
nod.child->accept(*this);
openList.pop_back();
};
我对此感到困惑的主要原因有两个:
- 两个不同的构造函数导致不同数量的泄漏
- 据报道泄漏发生在访问期间
所有节点的 accept
方法只是触发对正确访问者的 visit
方法的标准双重分派。
我是 C++ 编程的新手,可能忽略了一些非常基本的问题。
copyCreator<nodeType>::push(ptr)
应该取得 ptr
的所有权。但如果 (a) ptr
不是 nodeType*
类型(由 dynamic_cast
确定),并且 (b) 没有 nodeType
类型的节点已经还没去过
换句话说,copyCreator<nodeType>
创建并迅速泄漏所有节点的副本,直到它遇到类型 nodeType
。
这正是 copyCreator<programNode> cpy2(&globalScope, a);
中发生的情况,其中 a
是 forallNode*
。 cpy2
期望遇到 programNode
(它从未遇到过),同时,它复制并泄漏所有其他节点。
我正在开发一个使用访问者模式的中型 C++ 框架。
对实现此框架的程序进行的 valgrind 测试报告了一些内存泄漏,这些内存泄漏可以追溯到其中一位访客,即 copyCreator
。
template<typename copyNodeType>
struct copyCreator {
copyCreator {}
copyCreator(node * firstVisit) {
firstVisit->accept(*this);
}
~copyCreator() {
copy.reset();
for(auto ptr : openList) {
delete ptr;
}
}
std::unique_ptr<copyNodeType> copy = 0;
vector<nonterminalNode *> openList;
// push to tree
template<typename nodeType>
void push(nodeType * ptr) {
if (copy) {
// if root is set, append to tree
openList.back()->add_child(ptr);
}
else {
auto temp = dynamic_cast<copyNodeType *>(ptr);
if(temp) {
copy = std::unique_ptr<copyNodeType>(temp);
}
}
}
// ...
void visit(struct someNonterminalNode & nod) {
auto next = new someNonterminalNode(); //This is leaked
push(next);
openList.push_back(next);
nod.child->accept(*this);
openList.pop_back();
};
我对此感到困惑的主要原因有两个:
- 两个不同的构造函数导致不同数量的泄漏
- 据报道泄漏发生在访问期间
所有节点的 accept
方法只是触发对正确访问者的 visit
方法的标准双重分派。
我是 C++ 编程的新手,可能忽略了一些非常基本的问题。
copyCreator<nodeType>::push(ptr)
应该取得 ptr
的所有权。但如果 (a) ptr
不是 nodeType*
类型(由 dynamic_cast
确定),并且 (b) 没有 nodeType
类型的节点已经还没去过
换句话说,copyCreator<nodeType>
创建并迅速泄漏所有节点的副本,直到它遇到类型 nodeType
。
这正是 copyCreator<programNode> cpy2(&globalScope, a);
中发生的情况,其中 a
是 forallNode*
。 cpy2
期望遇到 programNode
(它从未遇到过),同时,它复制并泄漏所有其他节点。