0

Описание проблемы

Я пытаюсь закодировать класс Node для графа. Каждый узел представлен:Правило трех исключений указателя во время выполнения (Graph-Node)

  • ID
  • расстояние
  • родительский узел

Я закодировал следующие три функции:

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

В тот момент я назначить родительский узел существующий узел. Во время выполнения я получаю огромное исключение. хорошая вещь, я не взорвал компьютер. Правильно ли кодирую следующие три функции?

Я удалил функции получения и сеттера расстояния и идентификатора, чтобы сократить код.

спасибо.


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] 
+0

Я думаю, что это другая проблема, но у вас есть возможная утечка памяти в вашей функции 'setParent'. Если вы не проверяете, является ли текущий '_parent' нулевым, а если нет, удалите то, что там? Из вашего дизайна неясно, какая часть кода будет управлять той частью памяти ... – Brick

+0

@Brick, где я должен проверить, является ли текущий родитель нулевым? Я действительно не понимал. –

+0

'void Node :: setParent (Node * parent) { _parent = parent; } 'Что, если' _parent' не является нулевым, когда вы называете это? – Brick

ответ

0

Проблема не вызвана n3.setParent (& n4); вы можете проверить это, добавив {char c; cin >> c;} после этого утверждения и до конца main().

Проблема вызвана if (_parent! = Nullptr) delete _parent;

Узлы n0-n4 создаются в стеке main() и поэтому будут удаляться при завершении main(). Тем не менее, один из узлов уже отправлен командой delete в деструкторе, что дает вам ошибку free(): invalid pointer: 0x00007ffecf36b250.

Используйте delete для объектов, которые были созданы с новыми.

+0

Я протестировал следующее. Сохраняя 'if (_parent! = Nullptr) delete _parent;' 'Node * n0 = new Node (0); Узел * n1 = новый узел (1); Узел * n2 = новый узел (2); Узел * n3 = новый узел (3); n3-> setParent (n2); ' на этот раз сработал. спасибо за ваше объяснение. теперь для меня это более понятно. Я предполагаю, что мне действительно нужно понять, как работает память в C++. –

Смежные вопросы