   A* and memory issue (pointers)
  So, wanting to look at creating an implementation of A* (vaguely using the article on here) I set about coding one.  Now, the good news is that it works, the not so good news is that it slowly but surely eats memory (when run continually) and I know it's down to my pointers.  I can delete my open list with no issues (and slowed the rate memory was increasing quite a lot) but trying to do the same with my closed list causes it to crash.  I'm hoping someone can take a look through what I've done and point out the error of my ways so I can carry on with the demo/project. :)A-Star implementation below:#include "A-star.h"#define MAP_STEP 10#define MAP_STEP_DIAG 14#define BLOCKED 9void AStar::Calculate(int StartX, int StartY, int GoalX, int GoalY){// Set start and end positionsm_iStartX = StartX; m_iStartY = StartY;m_iGoalX = GoalX;m_iGoalY = GoalY;// Check start and goal is not the sameif( (m_iStartX == m_iGoalX) && (m_iStartY == m_iGoalY) ){// No need to calculate path/*Add any other neccessary code here*/return;}// Check the goal (destination) is validif(!IsValid(m_iGoalX, m_iGoalY)){// Goal (destination) is not valid, do not calculate path/*Add any other neccessary code here*/return;}// Set the start nodem_StartNode = new Node(m_iStartX, m_iStartY);CalculateHeuristic(m_StartNode);m_ClosedList.clear();m_OpenList.clear();m_OpenList.push_back(m_StartNode);CalculatePath();delete m_StartNode;}void AStar::CalculatePath(){steps = 0;steps2 = 0;dist = 0;while(1){++steps;Node* cheapest = GetCheapestOpenNode();// Check whether the node is the goalif( cheapest->x == m_iGoalX && cheapest->y == m_iGoalY ){m_ClosedList.push_back(cheapest);break;}std::vector<Node* >::iterator nodeIt;std::vector<Node* > adjNodes = FindAdjacentNodes(cheapest);for( nodeIt = adjNodes.begin(); nodeIt != adjNodes.end(); ++nodeIt){++steps2;CalculateGCost(*nodeIt);bool bInOpenList(false);if( ExistsInClosedList(*nodeIt) ){continue;}else if( ExistsInOpenList(*nodeIt) ){bInOpenList = true;Node* inOpenList = GetNodeInOpenList(*nodeIt);// Check whether g score is lower than node in open listif( inOpenList->g <= (*nodeIt)->g ){continue;}else{// Node is already in OpenList and has lower g so update (done by replacing) itRemoveNodeInOpenList(inOpenList);(*nodeIt)->h = inOpenList->h;CalculateFCost((*nodeIt));m_OpenList.push_back(*nodeIt);}delete inOpenList;}else{// unvisited nodeCalculateHeuristic(*nodeIt);}CalculateFCost(*nodeIt);if(!bInOpenList){m_OpenList.push_back(*nodeIt);}}MoveFromOpenToClosedList(cheapest);}std::vector<Node* >::iterator it;it = m_ClosedList.end(); --it; dist = (*it)->g;for(unsigned int i(0); i < m_OpenList.size(); ++i){delete(m_OpenList);}// Below causes crash/*for(unsigned int i(0); i < m_ClosedList.size(); ++i){delete(m_ClosedList);}*/}////  Desc:  Returns valid adjacent nodes to the node provided//std::vector<Node* > AStar::FindAdjacentNodes(Node* currentNode){std::vector<Node *> adjNodes;// Topif( IsValid(currentNode->x, currentNode->y + 1) ){adjNodes.push_back( new Node(currentNode->x, currentNode->y + 1, MAP_STEP, currentNode) );}// Top rightif( IsValid(currentNode->x + 1, currentNode->y + 1) ){adjNodes.push_back( new Node(currentNode->x + 1, currentNode->y + 1, MAP_STEP_DIAG, currentNode) );}// Rightif( IsValid(currentNode->x + 1, currentNode->y) ){adjNodes.push_back( new Node(currentNode->x + 1, currentNode->y, MAP_STEP, currentNode) );}// Bottom Rightif( IsValid(currentNode->x + 1, currentNode->y - 1) ){adjNodes.push_back( new Node(currentNode->x + 1, currentNode->y - 1, MAP_STEP_DIAG,currentNode) );}// Bottomif( IsValid(currentNode->x, currentNode->y - 1) ){adjNodes.push_back( new Node(currentNode->x, currentNode->y - 1, MAP_STEP, currentNode) );}// Bottom leftif( IsValid(currentNode->x - 1, currentNode->y - 1) ){adjNodes.push_back( new Node(currentNode->x - 1, currentNode->y - 1, MAP_STEP_DIAG, currentNode) );}// Leftif( IsValid(currentNode->x - 1, currentNode->y) ){adjNodes.push_back( new Node(currentNode->x - 1, currentNode->y, MAP_STEP, currentNode) );}// Top Leftif( IsValid(currentNode->x - 1, currentNode->y + 1) ){adjNodes.push_back( new Node(currentNode->x - 1, currentNode->y + 1, MAP_STEP_DIAG, currentNode) );}return adjNodes;}////  Desc:  Move provided node from the Open list to the Closed list; node is removed from Open list//void AStar::MoveFromOpenToClosedList(Node* node){//Delete from Open Liststd::vector<Node* >::iterator it;it = find(m_OpenList.begin(), m_OpenList.end(), node);if (it != m_OpenList.end()){delete (*it);m_OpenList.erase(it); }//Add to Closed Listm_ClosedList.push_back(node);}////  Desc:  Checks whether the node provided is already in the Closed list//bool AStar::ExistsInClosedList(Node* node){std::vector<Node* >::iterator it;it = find(m_ClosedList.begin(), m_ClosedList.end(), node);if (it == m_ClosedList.end()){return false;}return true;}////  Desc:  Checks whether the node provided is in the Open List//bool AStar::ExistsInOpenList(Node* node){std::vector<Node* >::iterator it;it = find(m_OpenList.begin(), m_OpenList.end(), node);if (it == m_OpenList.end()){return false;}return true;}////  Desc:  Returns the node from the Open List//Node* AStar::GetNodeInOpenList(Node *node){std::vector<Node* >::iterator it;it = find(m_OpenList.begin(), m_OpenList.end(), node);return (*it);}////  Desc:  Gets the cheapest node from the Open List based on the node's F value//Node* AStar::GetCheapestOpenNode(){Node* cheapest = *m_OpenList.begin();std::vector<Node* >::iterator it;for(it = m_OpenList.begin(); it != m_OpenList.end(); ++it){if( (*it)->f < cheapest->f ){cheapest = (*it);}}return cheapest;}////  Desc:  Removes the provided node from the Open List//void AStar::RemoveNodeInOpenList(Node* node){std::vector<Node* >::iterator it;it = find(m_OpenList.begin(), m_OpenList.end(), node);//Erase if found itif (it != m_OpenList.end()){delete (*it);m_OpenList.erase(it);}}////  Desc:  Checks whether the node is valid (within bounds and is walkable)//bool AStar::IsValid(int x, int y){// Check selection is within the mapif ( (x < 0) || (y < 0) || (x > MAP_WIDTH) || (y > MAP_HEIGHT) ){return false;}// Check selection is walkableif( map[x][y] == BLOCKED ){return false;}return true;}////  Desc:  Calculates the Heuristic; estimated from node position to goal//void AStar::CalculateHeuristic(Node* node){// Using Manhattan methodint distToGoalX = (m_iGoalX - node->x);int distToGoalY = (m_iGoalY - node->y);node->h = static_cast<int>( sqrt( static_cast<double>((distToGoalX * distToGoalX) + (distToGoalY * distToGoalY)) ) ) * MAP_STEP;}////  Desc:  Claculates the G cost of the node//void AStar::CalculateGCost(Node* node){node->g += node->parent->g;}////  Desc:  Calculates the F cost of the node//void AStar::CalculateFCost(Node* node){node->f = node->g + node->h;}Node implementation below:parent is defined as: Node* parent;Node::Node():f(0),g(0),h(0),x(0),y(0),parent(0){}Node::Node(int x, int y):f(0),g(0),h(0),x(x),y(y),parent(0){}Node::Node(int x, int y, int g, Node* node):f(0),g(g),h(0),x(x),y(y),parent(node){}Node::Node(Node* node):f(node->f),g(node->g),h(node->h),x(node->x),y(node->y),parent(node){}Node::~Node(){if(parent != 0){parent = 0;delete parent;}}Thanks!   
  When you've found your destination, you add cheapestNode to the closed list, but you're not removing it from the open list. So you're deleting the same Node twice. Everything that's new'ed should be deleted when it's no longer needed, but you shouldn't be overzealous by deleting the same thing twice. ;)Bytheway, your Node destructor looks peculiar. Just leave it empty - you'd only set pointers to 0 (NULL) in a destructor if you're facing a deadline and a memory corruption problem. Calling delete on a null pointer doesn't do anything, either. ;)   ;Node::~Node(){if(parent != 0){parent = 0;delete parent;}}You're nullifying the pointer and then deleting it - this should be the other way around (if required at all):Node::~Node(){if(parent != 0){delete parent;parent = 0;}};  The AStar class creates the nodes, so it should clean them up as well. Nodes should not clean up their parents, because those parent nodes are already managed by AStar.Memory management is easy to mess up with, so you'd better stick to strict rules with regards to ownership. Generally, the more you can automate, the better. You may want to read up on smart pointers and RAII.   ;  Cheers guys, all sorted now. :)@Barguast: It wasn't needed and wasn't part of the class when I created it but through trying things out rather than taking a step back and looking at it it found it's way there.@Captain P: Good spot.  That was part of the issue (the function itself was the root cause) and with a little stepping through realised where I had gone wrong and got it sorted.   