简体   繁体   中英

Rule of three pointer exception at run-time (Graph-Node)

Problem description

I am trying to code a class Node for a graph. Every node is represented by :

  • ID
  • distance
  • parent node

I coded the following three functions:

Node(const Node &);
Node & operator=(const Node & );
~Node();

The moment I assign a parent node to an existing node. At run time I get a huge exception. good thing i didn't blow up the pc. Am I coding correctly the following three functions?

I removed the getter and setter functions of distance and id to shorten to code.

thank you.


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;
}

problem

in the main everything goes well:

    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;

Till I do this:

====>n3.setParent(&n4);<====== . At runtime i get the following:

*** 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]

The problem is not caused by n3.setParent(&n4); you can check this by adding {char c; cin >> c;} after this statement, and before the end of main().

The problem is caused by if (_parent != nullptr) delete _parent;

Nodes n0-n4 are created on the stack of main(), and so will be deleted when main() ends. However, one of the Nodes is already gone by the delete statement in the destructor, which gives you the free(): invalid pointer: 0x00007ffecf36b250 error.

Use delete for objects that have been created with new.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM