【发布时间】:2012-07-26 11:40:34
【问题描述】:
在下面的代码中,我在返回 1 后得到以下运行时异常(可能是内存泄漏);并在 Node() 的析构函数中。
Unhandled exception at 0x0f9bad4a (msvcp100d.dll) in test.exe: 0xC0000005: Access violation reading location 0xfeeefef2.
自从我使用 smart_ptr 已经有一段时间了,所以我想知道我在这里做错了什么?
#include <vector>
#include <queue>
#include <memory>
#include <iostream>
using namespace std;
class Node;
typedef shared_ptr<Node> SharedNode;
class Node {
Node* parent;
vector< SharedNode > children;
int value;
//limiting construction
Node(int a_value):value(a_value),parent(0){}
Node(const Node ©); //non-construction-copyable
Node& operator=(const Node& copy); //non-copyable
public:
static SharedNode create(int a_value){
return SharedNode(new Node(a_value));
}
SharedNode addChild(SharedNode child){
child->parent = this;
children.push_back(child);
return child;
}
SharedNode getNode(int searchValue);
};
SharedNode Node::getNode(int searchValue){
// Breadth First Search
queue<SharedNode> que;
que.push(SharedNode(this));
while(!que.empty()){
SharedNode node = que.front();
que.pop();
if(node->value == searchValue)
return node;
vector<SharedNode>::iterator it;
for(it = node->children.begin(); it != node->children.end(); it++){
que.push(*it);
}
}
return 0;
}
int main(){
SharedNode node_ptr = Node::create(5);
for(int i = 0; i < 4; ++i)
node_ptr->addChild(Node::create(i));
cout << (node_ptr->getNode(-1) != 0 ? "Found" : "Not found");
return 1;
}
我想我在使用 shared_ptr 时搞砸了,比如:shared_ptr(this)。但是,那是我的猜测。
我在这里做错了什么?
【问题讨论】:
-
你有一个双重删除,
0xfeeefef2表示的。它与0xfeeefeee仅相差几个字节,这是 Windows 调试堆的“已释放内存”模式。是的,问题在于从this构造shared_ptr。shared_ptr拥有所有权,但是当this存在时,其他东西已经拥有所有权。重新思考您的设计。 -
我感觉
que.push(SharedNode(this));是getNode()函数的罪魁祸首。 -
当您构建具有单亲的结构时,为什么需要共享语义?这对我来说毫无意义。这里的一切都可以通过范围来控制。
-
@pmr 你能详细说明一下吗?
-
@brainydexter 您正在构建一棵带有来自孩子的反向引用的树。一切的生命周期取决于根。这里根本没有共享数据:只有所有权和观察者。父母拥有孩子,孩子观察父母。当父级被删除时,它的所有子级都会被删除。但是您可能在某处有一个用例,例如孩子比父母活得更久,但可以有更好的解决方案。
标签: c++ shared-ptr