I am getting a double free error when I run my code and don't know why. The relevant code is just an a* traversal and the double free is happening when I delete my tree. To get the code out of the way, here it is. (tried to get rid of as much irrelevant stuff as I could).
a* traversal -
Code:Path Agent::traverse(Position& end) { //std::cout<<"\nTraversing from "<<pos.toString()<<" to "<<end.toString(); //make tree and add the start position as the root node Tree* tree = new Tree(pos); //set root node values tree->getRoot()->setGValue(0); tree->getRoot()->setHValue(getSLDistance(pos,end)); tree->getRoot()->setFValue(); tree->getRoot()->setParent(tree->getRoot()); //make priority queue of todo nodes and add root PriorityQueue nodes; nodes.push(tree->getRoot()); //make path to return Path result; //flag to stop bool done = false; Tree::Node* parent = tree->getRoot(); //the parent to current for robot tracing Tree::Node* current = tree->getRoot(); //best node //**grid->setPos(current->getValue().getRow(), current->getValue().getCol(), 'x'); //set initial spot on grid //start traversing while(!done) { //if the queue is empty, there is no path if(nodes.isEmpty()) { Position temp = find_next_best(*tree, end); goal = temp; delete tree; return traverse(temp); } //else there are more positions to try else { //std::cout<<"\nTREE WHEN CURRENT IS "<<current->getValue().toString()<<tree->toString(); //set the new parent parent = current; //else, set grid and set current to best node //**grid->setPos(current->getValue().getRow(), current->getValue().getCol(), ' '); current = nodes.top(); //**grid->setPos(current->getValue().getRow(), current->getValue().getCol(), 'x'); //**std::cout<<grid->toString(); //if agreed to best move, pop off node if(current == nodes.top()) nodes.pop(); //if we are at the goal, end loop if(current->getValue().equals(end)) done = true; //else, traverse further else { //get successor nodes for current std::vector<Position> successors = adjacentPositions(current->getValue()); //for each successor for(int i=0;i<successors.size();i++) { //if not equal to an ancestor node if(!tree->contains(successors.at(i))) { //make temp node for the tree Tree::Node temp(successors.at(i), current); //set the g value to current.gvalue + step cost (step cost is always 1) temp.setGValue(current->getGValue() + 1); //set h value temp.setHValue(getSLDistance(temp.getValue(), end)); //set f value temp.setFValue(); //make a node* for queue Tree::Node* t = tree->add(temp.getValue(), current); //set function values t->setGValue(temp.getGValue()); t->setHValue(temp.getHValue()); t->setFValue(); //push into queue nodes.push(t); } //end if successor not an ancestor node } //end for } //end else not at goal } //end else still positions to try } //end while //TRACE BACK UP THE NODES TO GET THE PATH while(!(current->getValue().equals(tree->getRoot()->getValue()))) { result.add(current->getValue()); current = current->getParent(); } //push root position result.add(current->getValue()); result.reverse(); delete tree; return result; } //END TRAVERSE Position Agent::find_next_best(Tree tree, Position e) { Position result; Tree::Node* nb = tree.getNodes().at(0); for(int i=1;i<tree.getNodes().size();i++) { //check straight line distance if( tree.getNodes().at(i)->getHValue() < nb->getHValue() ) nb = tree.getNodes().at(i); //if straight line distance is equal, check step cost else if( tree.getNodes().at(i)->getHValue() == nb->getHValue() ) if( tree.getNodes().at(i)->getGValue() < nb->getGValue() ) nb = tree.getNodes().at(i); } //end for result = nb->getValue(); //std::cout<<"\nFIND NEXT BEST RETURNING: "<<result.toString(); return result; }
tree.h -
Code:class Tree { public: class Node { public: Node() {} Node(const Node&); //! A Constructor /*! * Sets value to v and parent to p */ Node(Position&, Node*&); //! A Destructor ~Node(); //! Clones a Node /*! * Returns a Node instance whose members are equal to this Node's members */ Node clone(Node*&); //! Check if Node is a leaf /*! * Returns true if Node has zero children */ bool isLeaf(); //! Getter function for value member /*! * Returns a reference of the value member */ Position& getValue(); //! Setter function for value member /*! * Sets value to v */ void setValue(Position&); //! Getter function for parent member /*! * Returns a reference of the parent member */ Node*& getParent(); //! Setter function for parent member /*! * Sets parent to p */ void setParent(Node*&); //! Getter function for gvalue member /*! * Returns value of gvalue member */ double getGValue(); //! Setter for gvalue member /*! * Sets gvalue to v */ void setGValue(double); //! Getter function for hvalue member /*! * Returns value of hvalue member */ double getHValue(); //! Setter function for hvalue member /*! * Returns value of hvalue member */ void setHValue(double); //! Getter function for fvalue member /*! * Returns value of fvalue member */ double getFValue(); //! Setter function for fvalue member /*! * Sets fvalue to v */ void setFValue(); //! Getter function for children member /*! * Returns reference of the children member */ std::vector<Node*>& getChildren(); //! Returns a printable string of the Node std::string toString(); Tree::Node clone(); Node& operator=(const Node&); private: double gvalue; double hvalue; double fvalue; Position value; Node* parent; std::vector<Node*> children; }; //END NODE CLASS //! Exception class for when a Node is not found class NodeNotFoundException : public std::exception { public: virtual const char* what() const throw(); }; //end exception //! A Constructor /*! Sets root to p */ Tree(Position&); //! A Destructor ~Tree(); //! Getter function for root member /*! Returns a reference of root member */ Node*& getRoot(); std::vector<Node*> getNodes(); //! Checks if a Position is in the tree /*! Returns true if a Position in the tree is equal to p */ bool contains(Position&); //! Add a Position to the tree /*! Makes a node for value and adds that node to the tree as one of parent's children */ Node* add(Position&, Node*&); //! Returns a printable string for the root node of the tree std::string rootToString(); //! Returns a printable string of a subtree /*! * Returns a printable string of a subtree\n * Treats t as the root */ std::string toString(Node*&); //! Returns a printable string of the while tree std::string toString(); private: //root of tree Node* dummyroot; Node* root; std::vector<Node*> nodes; }; #endif
tree.cpp with some irrelevant stuff taken out -
Code:Tree::Node::Node(const Node& right) { gvalue = right.getGValue(); hvalue = right.getHValue(); fvalue = right.getFValue(); value = right.getValue(); parent = right.getParent(); children = right.getChildren(); } /*Constructor*/ Tree::Node::Node(Position& v, Node*& p) : value(v), parent(p), gvalue(0), hvalue(0), fvalue(0) {} /*Destructor*/ Tree::Node::~Node() {} Tree::Node Tree::Node::clone() {return *this;} Tree::Node& Tree::Node::operator=(const Tree::Node& right) { if(this != &right) { gvalue = right.getGValue(); hvalue = right.getHValue(); fvalue = right.getFValue(); value = right.getValue(); parent = right.getParent(); children = right.getChildren(); } return *this; } /*Constructor that sets p as the root value*/ Tree::Tree(Position& p) { Node* temp = new Node(p, dummyroot); root = temp; nodes.push_back(temp); } //END CONSTRUCTOR /*Destructor*/ Tree::~Tree() { for(int i=0;i<nodes.size();i++) delete nodes.at(i); } /*Returns true if p is in the tree*/ bool Tree::contains(Position& p) { for(int i=0;i<nodes.size();i++) if(p.equals(nodes.at(i)->getValue())) return true; return false; } //END CONTAINS Tree::Node* Tree::add(Position& value, Node*& parent) { Node* temp = new Node(value, parent); parent->getChildren().push_back(temp); //std::cout<<"\n"<<temp->getValue().toString()<<" added to "<<parent->getValue().toString(); nodes.push_back(temp); return temp; } //END ADD
When I run the code, I get an error of -
Code:*** glibc detected *** /home/sterling/Desktop/irobot_driverprac/go: double free or corruption (out): 0xb59004d0 *** ======= Backtrace: ========= /lib/i686/cmov/libc.so.6(+0x6b281)[0xb7b7d281] /lib/i686/cmov/libc.so.6(+0x6cad8)[0xb7b7ead8] /lib/i686/cmov/libc.so.6(cfree+0x6d)[0xb7b81bbd] /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7d57701] /home/sterling/Desktop/irobot_driverprac/go[0x804f83e] /home/sterling/Desktop/irobot_driverprac/go[0x804bc4d] /home/sterling/Desktop/irobot_driverprac/go[0x8059b27] /home/sterling/Desktop/irobot_driverprac/go[0x8059849] /lib/i686/cmov/libpthread.so.0(+0x5955)[0xb7fbb955] /lib/i686/cmov/libc.so.6(clone+0x5e)[0xb7bdde7e] ======= Memory map: ======== 08048000-08063000 r-xp 00000000 08:01 2113591 /home/sterling/Desktop/irobot_driverprac/go 08063000-08064000 rw-p 0001b000 08:01 2113591 /home/sterling/Desktop/irobot_driverprac/go 08064000-08085000 rw-p 00000000 00:00 0 [heap] b5900000-b5921000 rw-p 00000000 00:00 0 b5921000-b5a00000 ---p 00000000 00:00 0 b5a30000-b5a31000 ---p 00000000 00:00 0 b5a31000-b6231000 rw-p 00000000 00:00 0 b6231000-b6232000 ---p 00000000 00:00 0 b6232000-b6a32000 rw-p 00000000 00:00 0 b6a32000-b6a33000 ---p 00000000 00:00 0 b6a33000-b7233000 rw-p 00000000 00:00 0 b7233000-b7234000 ---p 00000000 00:00 0 b7234000-b7a35000 rw-p 00000000 00:00 0 b7a35000-b7a39000 r-xp 00000000 08:01 12913515 /usr/lib/libXdmcp.so.6.0.0 b7a39000-b7a3a000 rw-p 00003000 08:01 12913515 /usr/lib/libXdmcp.so.6.0.0 b7a3a000-b7a3b000 rw-p 00000000 00:00 0 b7a3b000-b7a3d000 r-xp 00000000 08:01 12913513 /usr/lib/libXau.so.6.0.0 b7a3d000-b7a3e000 rw-p 00001000 08:01 12913513 /usr/lib/libXau.so.6.0.0 b7a3e000-b7a56000 r-xp 00000000 08:01 12913517 /usr/lib/libxcb.so.1.1.0 b7a56000-b7a57000 rw-p 00017000 08:01 12913517 /usr/lib/libxcb.so.1.1.0 b7a57000-b7a7b000 r-xp 00000000 08:01 12911203 /usr/lib/libexpat.so.1.5.2 b7a7b000-b7a7d000 rw-p 00023000 08:01 12911203 /usr/lib/libexpat.so.1.5.2 b7a7d000-b7a90000 r-xp 00000000 08:01 12912908 /usr/lib/libz.so.1.2.3.4 b7a90000-b7a91000 rw-p 00013000 08:01 12912908 /usr/lib/libz.so.1.2.3.4 b7a91000-b7a99000 r-xp 00000000 08:01 12913527 /usr/lib/libXrender.so.1.3.0 b7a99000-b7a9a000 rw-p 00007000 08:01 12913527 /usr/lib/libXrender.so.1.3.0 b7a9a000-b7a9b000 rw-p 00000000 00:00 0 b7a9b000-b7b0e000 r-xp 00000000 08:01 12913496 /usr/lib/libfreetype.so.6.6.0 b7b0e000-b7b12000 rw-p 00073000 08:01 12913496 /usr/lib/libfreetype.so.6.6.0 b7b12000-b7c52000 r-xp 00000000 08:01 8307784 /lib/i686/cmov/libc-2.11.2.so b7c52000-b7c54000 r--p 0013f000 08:01 8307784 /lib/i686/cmov/libc-2.11.2.so b7c54000-b7c55000 rw-p 00141000 08:01 8307784 /lib/i686/cmov/libc-2.11.2.so b7c55000-b7c58000 rw-p 00000000 00:00 0 b7c58000-b7c75000 r-xp 00000000 08:01 8290307 /lib/libgcc_s.so.1 b7c75000-b7c76000 rw-p 0001c000 08:01 8290307 /lib/libgcc_s.so.1 b7c76000-b7c9a000 r-xp 00000000 08:01 8307768 /lib/i686/cmov/libm-2.11.2.so b7c9a000-b7c9b000 r--p 00023000 08:01 8307768 /lib/i686/cmov/libm-2.11.2.so b7c9b000-b7c9c000 rw-p 00024000 08:01 8307768 /lib/i686/cmov/libm-2.11.2.so b7c9c000-b7d85000 r-xp 00000000 08:01 12912463 /usr/lib/libstdc++.so.6.0.13 b7d85000-b7d89000 r--p 000e9000 08:01 12912463 /usr/lib/libstdc++.so.6.0.13 b7d89000-b7d8a000 rw-p 000ed000 08:01 12912463 /usr/lib/libstdc++.so.6.0.13 b7d8a000-b7d91000 rw-p 00000000 00:00 0 b7d91000-b7eaa000 r-xp 00000000 08:01 12913521 /usr/lib/libX11.so.6.3.0 b7eaa000-b7eae000 rw-p 00118000 08:01 12913521 /usr/lib/libX11.so.6.3.0 b7eae000-b7eaf000 rw-p 00000000 00:00 0 b7eaf000-b7eb1000 r-xp 00000000 08:01 8307776 /lib/i686/cmov/libdl-2.11.2.so b7eb1000-b7eb2000 r--p 00001000 08:01 8307776 /lib/i686/cmov/libdl-2.11.2.so b7eb2000-b7eb3000 rw-p 00002000 08:01 8307776 /lib/i686/cmov/libdl-2.11.2.so b7eb3000-b7eb5000 r-xp 00000000 08:01 12915615 /usr/lib/libXinerama.so.1.0.0 b7eb5000-b7eb6000 rw-p 00001000 08:01 12915615 /usr/lib/libXinerama.so.1.0.0 b7eb6000-b7ee3000 r-xp 00000000 08:01 12913509 /usr/lib/libfontconfig.so.1.4.4 b7ee3000-b7ee5000 rw-p 0002c000 08:01 12913509 /usr/lib/libfontconfig.so.1.4.4 b7ee5000-b7ef7000 r-xp 00000000 08:01 12915587 /usr/lib/libXft.so.2.1.13 b7ef7000-b7ef8000 rw-p 00011000 08:01 12915587 /usr/lib/libXft.so.2.1.13 b7ef8000-b7f06000 r-xp 00000000 08:01 12915603 /usr/lib/libXext.so.6.4.0 b7f06000-b7f07000 rw-p 0000d000 08:01 12915603 /usr/lib/libXext.so.6.4.0 b7f07000-b7f08000 rw-p 00000000 00:00 0 b7f08000-b7fad000 r-xp 00000000 08:01 418614 /usr/lib/libfltk.so.1.1 b7fad000-b7fb2000 rw-p 000a4000 08:01 418614 /usr/lib/libfltk.so.1.1 b7fb2000-b7fb6000 rw-p 00000000 00:00 0 b7fb6000-b7fcb000 r-xp 00000000 08:01 8307773 /lib/i686/cmov/libpthread-2.11.2.so b7fcb000-b7fcc000 r--p 00014000 08:01 8307773 /lib/i686/cmov/libpthread-2.11.2.so b7fcc000-b7fcd000 rw-p 00015000 08:01 8307773 /lib/i686/cmov/libpthread-2.11.2.so b7fcd000-b7fcf000 rw-p 00000000 00:00 0 b7fde000-b7fe2000 rw-p 00000000 00:00 0 b7fe2000-b7fe3000 r-xp 00000000 00:00 0 [vdso] b7fe3000-b7ffe000 r-xp 00000000 08:01 8290329 /lib/ld-2.11.2.so b7ffe000-b7fff000 r--p 0001a000 08:01 8290329 /lib/ld-2.11.2.so b7fff000-b8000000 rw-p 0001b000 08:01 8290329 /lib/ld-2.11.2.so bffeb000-c0000000 rw-p 00000000 00:00 0 [stack]
with a backtrace of -
Code:#0 0xb7fe2424 in __kernel_vsyscall () #1 0xb7b3c751 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #2 0xb7b3fb82 in *__GI_abort () at abort.c:92 #3 0xb7b7318d in __libc_message (do_abort=2, fmt=0xb7c37738 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:189 #4 0xb7b7d281 in malloc_printerr (action=<value optimized out>, str=0x6 <Address 0x6 out of bounds>, ptr=0xb59004d0) at malloc.c:6267 #5 0xb7b7ead8 in _int_free (av=<value optimized out>, p=<value optimized out>) at malloc.c:4795 #6 0xb7b81bbd in *__GI___libc_free (mem=0xb59004d0) at malloc.c:3739 #7 0xb7d57701 in operator delete(void*) () from /usr/lib/libstdc++.so.6 #8 0x0804f83e in __gnu_cxx::new_allocator<Tree::Node*>::deallocate (this=0x8066900, __in_chrg=<value optimized out>) at /usr/include/c++/4.4/ext/new_allocator.h:95 #9 std::_Vector_base<Tree::Node*, std::allocator<Tree::Node*> >::_M_deallocate ( this=0x8066900, __in_chrg=<value optimized out>) at /usr/include/c++/4.4/bits/stl_vector.h:146 #10 ~_Vector_base (this=0x8066900, __in_chrg=<value optimized out>) at /usr/include/c++/4.4/bits/stl_vector.h:132 #11 ~vector (this=0x8066900, __in_chrg=<value optimized out>) at /usr/include/c++/4.4/bits/stl_vector.h:313 #12 ~Node (this=0x8066900, __in_chrg=<value optimized out>) at tree.cpp:24 #13 ~Tree (this=0x8066900, __in_chrg=<value optimized out>) at tree.cpp:108 #14 0x0804bc4d in Agent::traverse (this=0x8066710, end=...) at agent.cpp:189 #15 0x08059b27 in ServerControl::update_path_thread_i (this=0xbffff38c, client=1) at servercontrol.cpp:69 #16 0x08059849 in ServerControl::update_path1_thread (threadid=0xbffff38c) at servercontrol.cpp:27 #17 0xb7fbb955 in start_thread (arg=0xb6a31b70) at pthread_create.c:300 #18 0xb7bdde7e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
What I want to do when I delete a tree is just go through the vector of Node* and delete each one.
I have read that not having a copy constructor and overloaded assignment operator can cause this problem with vectors. But I added those and nothing (visible to me) changed.
I think the problem has to with the recursive call in traverse somehow, but if I take out the delete before the recursion call I will have a memory leak because I will not be deleting the tree.
Any help would be very appreciated.



1Likes
LinkBack URL
About LinkBacks


