运行-时间的三指针异常规则(Graph-Node)
Rule of three pointer exception at run-time (Graph-Node)
问题描述
我正在尝试为图表编写 class 节点。每个节点由 :
表示
- ID
- 距离
- 父节点
我编写了以下三个函数:
Node(const Node &);
Node & operator=(const Node & );
~Node();
我将父节点分配给现有节点的那一刻。在 运行 的时候我得到了一个巨大的异常。幸好我没有炸毁电脑。我是否正确编码了以下三个函数?
我删除了distance和id的getter和setter函数以缩短代码。
谢谢。
Node.h
#ifndef NODE_H
#define NODE_H
class Node{
public:
Node(int);
//rule of three
Node(const Node &);
Node & operator=(const Node & );
~Node();
//getters and setters
int getId() const;
int getDistance() const;
Node* getParent() const;
void setParent(Node *);
void setDistance(int);
private:
int _distance;
int _id;
Node * _parent;
};
#endif
node.cpp
#include "node.h"
Node::Node(int id):_id(id),_distance(INT_MAX),_parent(nullptr){}
Node::Node(const Node & other):_distance(other.getDistance()),_parent(nullptr){
cout << "copy constructor " << endl;
_parent = new Node(other.getId());
if(other.getParent() != nullptr){
_parent->setParent(other.getParent());
}
}
Node::~Node(){
cout <<"destructor" << endl;
if(_parent != nullptr)
delete _parent;
}
Node & Node::operator=(const Node& other){
cout << "assignment " << endl;
//self reference
if(this == &other){
return *this;
}
if(other.getParent() != nullptr){
_parent->setParent(other.getParent());
}
_id = other.getId();
_distance = other.getDistance();
return *this;
}
Node* Node::getParent() const{
return _parent;
}
int Node::getId() const{
return _id;
}
void Node::setParent(Node * parent){
_parent = parent;
}
问题
总的来说一切顺利:
Node n0(0);
Node n1(1);
Node n2(2);
Node n3(3);
// constructor(n0);
Node n4 = n0;
cout << n4.getParent() << endl;
cout << n0.getParent() << endl;
直到我这样做:
====>n3.setParent(&n4);<======。在 运行 时,我得到以下信息:
*** Error in `./graph': free(): invalid pointer: 0x00007ffecf36b250 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fd4b50637e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7fd4b506be0a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fd4b506f98c]
./graph[0x401007]
./graph[0x406128]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fd4b500c830]
./graph[0x400df9]
======= Memory map: ========
00400000-0040a000 r-xp 00000000 08:08 1442084 /home/hani/Documents/dataStructurecplusplus/graph/graph
00609000-0060a000 r--p 00009000 08:08 1442084 /home/hani/Documents/dataStructurecplusplus/graph/graph
0060a000-0060b000 rw-p 0000a000 08:08 1442084 /home/hani/Documents/dataStructurecplusplus/graph/graph
009f1000-00a23000 rw-p 00000000 00:00 0 [heap]
7fd4b0000000-7fd4b0021000 rw-p 00000000 00:00 0
7fd4b0021000-7fd4b4000000 ---p 00000000 00:00 0
7fd4b4cdc000-7fd4b4de4000 r-xp 00000000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4de4000-7fd4b4fe3000 ---p 00108000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4fe3000-7fd4b4fe4000 r--p 00107000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4fe4000-7fd4b4fe5000 rw-p 00108000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4fec000-7fd4b51ab000 r-xp 00000000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b51ab000-7fd4b53ab000 ---p 001bf000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b53ab000-7fd4b53af000 r--p 001bf000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b53af000-7fd4b53b1000 rw-p 001c3000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b53b1000-7fd4b53b5000 rw-p 00000000 00:00 0
7fd4b53bc000-7fd4b53d2000 r-xp 00000000 08:08 3936718 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd4b53d2000-7fd4b55d1000 ---p 00016000 08:08 3936718 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd4b55d1000-7fd4b55d2000 rw-p 00015000 08:08 3936718 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd4b55d4000-7fd4b5746000 r-xp 00000000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5746000-7fd4b5946000 ---p 00172000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5946000-7fd4b5950000 r--p 00172000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5950000-7fd4b5952000 rw-p 0017c000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5952000-7fd4b5956000 rw-p 00000000 00:00 0
7fd4b595c000-7fd4b5982000 r-xp 00000000 08:08 3932330 /lib/x86_64-linux-gnu/ld-2.23.so
7fd4b5b80000-7fd4b5b81000 rw-p 00000000 00:00 0
7fd4b5b81000-7fd4b5b82000 r--p 00025000 08:08 3932330 /lib/x86_64-linux-gnu/ld-2.23.so
7fd4b5b82000-7fd4b5b83000 rw-p 00026000 08:08 3932330 /lib/x86_64-linux-gnu/ld-2.23.so
7fd4b5b83000-7fd4b5b85000 rw-p 00000000 00:00 0
7fd4b5b85000-7fd4b5b8b000 rw-p 00000000 00:00 0
7ffecf34c000-7ffecf36d000 rw-p 00000000 00:00 0 [stack]
7ffecf3bc000-7ffecf3be000 r--p 00000000 00:00 0 [vvar]
7ffecf3be000-7ffecf3c0000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
问题不是n3.setParent(&n4)引起的;您可以通过添加 {char c; cin >> c;} 在此语句之后,main() 结束之前。
问题是if (_parent != nullptr) delete _parent;
节点n0-n4是在main()的栈上创建的,所以当main()结束时会被删除。但是,其中一个节点已经被析构函数中的 delete 语句删除,这给了你 free(): invalid pointer: 0x00007ffecf36b250 error.
对使用 new 创建的对象使用 delete。
问题描述
我正在尝试为图表编写 class 节点。每个节点由 :
表示- ID
- 距离
- 父节点
我编写了以下三个函数:
Node(const Node &);
Node & operator=(const Node & );
~Node();
我将父节点分配给现有节点的那一刻。在 运行 的时候我得到了一个巨大的异常。幸好我没有炸毁电脑。我是否正确编码了以下三个函数?
我删除了distance和id的getter和setter函数以缩短代码。
谢谢。
Node.h
#ifndef NODE_H
#define NODE_H
class Node{
public:
Node(int);
//rule of three
Node(const Node &);
Node & operator=(const Node & );
~Node();
//getters and setters
int getId() const;
int getDistance() const;
Node* getParent() const;
void setParent(Node *);
void setDistance(int);
private:
int _distance;
int _id;
Node * _parent;
};
#endif
node.cpp
#include "node.h"
Node::Node(int id):_id(id),_distance(INT_MAX),_parent(nullptr){}
Node::Node(const Node & other):_distance(other.getDistance()),_parent(nullptr){
cout << "copy constructor " << endl;
_parent = new Node(other.getId());
if(other.getParent() != nullptr){
_parent->setParent(other.getParent());
}
}
Node::~Node(){
cout <<"destructor" << endl;
if(_parent != nullptr)
delete _parent;
}
Node & Node::operator=(const Node& other){
cout << "assignment " << endl;
//self reference
if(this == &other){
return *this;
}
if(other.getParent() != nullptr){
_parent->setParent(other.getParent());
}
_id = other.getId();
_distance = other.getDistance();
return *this;
}
Node* Node::getParent() const{
return _parent;
}
int Node::getId() const{
return _id;
}
void Node::setParent(Node * parent){
_parent = parent;
}
问题
总的来说一切顺利:
Node n0(0);
Node n1(1);
Node n2(2);
Node n3(3);
// constructor(n0);
Node n4 = n0;
cout << n4.getParent() << endl;
cout << n0.getParent() << endl;
直到我这样做:
====>n3.setParent(&n4);<======。在 运行 时,我得到以下信息:
*** Error in `./graph': free(): invalid pointer: 0x00007ffecf36b250 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fd4b50637e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7fd4b506be0a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fd4b506f98c]
./graph[0x401007]
./graph[0x406128]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fd4b500c830]
./graph[0x400df9]
======= Memory map: ========
00400000-0040a000 r-xp 00000000 08:08 1442084 /home/hani/Documents/dataStructurecplusplus/graph/graph
00609000-0060a000 r--p 00009000 08:08 1442084 /home/hani/Documents/dataStructurecplusplus/graph/graph
0060a000-0060b000 rw-p 0000a000 08:08 1442084 /home/hani/Documents/dataStructurecplusplus/graph/graph
009f1000-00a23000 rw-p 00000000 00:00 0 [heap]
7fd4b0000000-7fd4b0021000 rw-p 00000000 00:00 0
7fd4b0021000-7fd4b4000000 ---p 00000000 00:00 0
7fd4b4cdc000-7fd4b4de4000 r-xp 00000000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4de4000-7fd4b4fe3000 ---p 00108000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4fe3000-7fd4b4fe4000 r--p 00107000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4fe4000-7fd4b4fe5000 rw-p 00108000 08:08 3932346 /lib/x86_64-linux-gnu/libm-2.23.so
7fd4b4fec000-7fd4b51ab000 r-xp 00000000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b51ab000-7fd4b53ab000 ---p 001bf000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b53ab000-7fd4b53af000 r--p 001bf000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b53af000-7fd4b53b1000 rw-p 001c3000 08:08 3932341 /lib/x86_64-linux-gnu/libc-2.23.so
7fd4b53b1000-7fd4b53b5000 rw-p 00000000 00:00 0
7fd4b53bc000-7fd4b53d2000 r-xp 00000000 08:08 3936718 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd4b53d2000-7fd4b55d1000 ---p 00016000 08:08 3936718 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd4b55d1000-7fd4b55d2000 rw-p 00015000 08:08 3936718 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd4b55d4000-7fd4b5746000 r-xp 00000000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5746000-7fd4b5946000 ---p 00172000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5946000-7fd4b5950000 r--p 00172000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5950000-7fd4b5952000 rw-p 0017c000 08:08 7211138 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd4b5952000-7fd4b5956000 rw-p 00000000 00:00 0
7fd4b595c000-7fd4b5982000 r-xp 00000000 08:08 3932330 /lib/x86_64-linux-gnu/ld-2.23.so
7fd4b5b80000-7fd4b5b81000 rw-p 00000000 00:00 0
7fd4b5b81000-7fd4b5b82000 r--p 00025000 08:08 3932330 /lib/x86_64-linux-gnu/ld-2.23.so
7fd4b5b82000-7fd4b5b83000 rw-p 00026000 08:08 3932330 /lib/x86_64-linux-gnu/ld-2.23.so
7fd4b5b83000-7fd4b5b85000 rw-p 00000000 00:00 0
7fd4b5b85000-7fd4b5b8b000 rw-p 00000000 00:00 0
7ffecf34c000-7ffecf36d000 rw-p 00000000 00:00 0 [stack]
7ffecf3bc000-7ffecf3be000 r--p 00000000 00:00 0 [vvar]
7ffecf3be000-7ffecf3c0000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
问题不是n3.setParent(&n4)引起的;您可以通过添加 {char c; cin >> c;} 在此语句之后,main() 结束之前。
问题是if (_parent != nullptr) delete _parent;
节点n0-n4是在main()的栈上创建的,所以当main()结束时会被删除。但是,其中一个节点已经被析构函数中的 delete 语句删除,这给了你 free(): invalid pointer: 0x00007ffecf36b250 error.
对使用 new 创建的对象使用 delete。