c ++导航" Maze"节点神秘的错误

时间:2015-11-10 21:34:06

标签: c++ search stack depth

我有一个我似乎无法弄清楚的问题。下面是我的所有代码,详细说明了两个类System和Node。我正在创建的是一个程序,它读入一个文件并创建一个"迷宫" (节点)(节点),然后从指定的起始节点导航到指定的结束节点。

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <array>
#include <map>
#include <stack>
#include <queue>
using namespace std;

class Node
{
   public:
      Node(string newName);
      Node();
      void setNodeName(string newName);
      string getNodeName();
      void attachNewNode(Node *newNode, int direction);
      Node *getAttachedNode(int direction);
      bool visited;
   private:
      string name;
      Node *attachedNodes[4];
};

Node::Node(string newName)
{
   name = newName;
   visited = false;
}

Node::Node()
{
   visited = false;
}

void Node::setNodeName(string newName)
{
   name = newName;
}

string Node::getNodeName()
{
   return name;
}

void Node::attachNewNode(Node *newNode, int direction)
{
   attachedNodes[direction] = newNode;
}

Node* Node::getAttachedNode(int direction)
{
   return attachedNodes[direction];
}

节点文件格式如下所示:

9
A1
C3
A1 A2 B1 * *
A2 * B2 A1 *
A3 * B3 * *
B1 * * * A1
B2 B3 C2 * A2
B3 * * B2 A3
C1 C2 * * *
C2 C3 * C1 B2
C3 * * C2 *

其中9是要创建的节点数,A1是我们将开始导航的节点,C3是我们将尝试查找路径的节点,以下行代表节点本身和它们具有的指针与他们相关联。例如:

A1 A2 B1 * *

表示节点A1的指针指向北方的节点A2,东方的B1,南方的空白,西方的空白。

A2 * B2 A1 *

表示节点A2的指针指向北方的节点null,东方的B2,南方的A1,以及西方的null。

Maze文件我正在使用标题&#34; maze1.txt&#34;如下:

48 
A1 
H6 
A1 A2 B1 * * 
B1 B2 * * A1 
C1 C2 * * * 
D1 D2 E1 * * 
E1 * * * D1 
F1 F2 * * * 
G1 G2 H1 * * 
H1 * * * G1 
A2 A3 * A1 * 
B2 * C2 B1 * 
C2 * D2 C1 B2 
D2 D3 * D1 C2 
E2 E3 * * * 
F2 F3 G2 F1 * 
G2 * H2 G1 F2 
H2 H3 * * G2 
A3 * B3 A2 * 
B3 B4 * * A3 
C3 C4 D3 * * 
D3 * E3 D2 C3 
E3 * * E2 D3 
F3 F4 * F2 * 
G3 G4 * * * 
H3 H4 * H2 * 
A4 A5 B4 * * 
B4 B5 * B3 A4 
C4 * D4 C3 * 
D4 * E4 * C4 
E4 E5 F4 * D4 
F4 * G4 F3 E4 
G4 * * G3 F4 
H4 H5 * H3 * 
A5 A6 * A4 * 
B5 * C5 B4 * 
C5 C6 D5 * B5 
D5 * * * C5 
E5 E6 F5 E4 * 
F5 * * * E5 
G5 G6 H5 * * 
H5 * * H4 G5 
A6 * B6 A5 * 
B6 * * * A6 
C6 * * C5 * 
D6 * E6 * * 
E6 * F6 E5 D6 
F6 * * * E6 
G6 * H6 G5 * 
H6 * * * G6 

截至昨天,buildGraph()的代码工作并正确地为我提供了节点的地图室及其各自的字符串键。

class System
{
   public:
      System();
      void displayWelcome();
      void displayExit();
      void buildGraph(string filename);
      string getFileName();
      string getPath();
      map<string,Node> rooms;
      void printMap(map<string,Node> nodes);
      bool canMove(string currentNode);
      string move(string currentNode);
      Node startNode;
      Node endNode;
      Node empt;
   private:
      int numNodes;
};

System::System()
{
    empt.setNodeName("null");
}

void System::displayWelcome()
{
   cout << endl;
   cout << "========================================================" << endl;
   cout << "|      Welcome to the Automatic Maze Path Finder!      |" << endl;
   cout << "========================================================" << endl;
   cout << endl;
}

void System::displayExit()
{
   cout << "========================================================" << endl;
   cout << "|  Thank you for using the Automatic Maze Path Finder! |" << endl;
   cout << "========================================================" << endl;
   cout << endl;
}

void System::buildGraph(string filename)
{
   ifstream instream;
   instream.open(filename.c_str());
   string line;
   string data;
   int numLines = 1;
   int skipBlanks = 1;
   int numNodes;

   while(getline(instream, line))
   {
      if(line.empty() || line.length() < 2)
      {}
      else
      {
         istringstream iss(line);

         if(numLines == 1)
         {
            istringstream buffer(line);
            buffer >> numNodes;
            skipBlanks++;
         }
         if(numLines == 2)
         {
            startNode.setNodeName(line);
            skipBlanks++;
            //cout << "start node is: " << startNode.getNodeName() << endl;
         }
         if(numLines == 3)
         {
            endNode.setNodeName(line);
            skipBlanks++;
            //cout << "end node is: " << endNode.getNodeName() << endl;
         }

         if(numLines > 3 && skipBlanks > 3)
         {
            Node temp;
            string nodeName = line.substr(0,2);

            //cout << "Line number: " << numLines << "  nodeName: " << nodeName << endl;

            rooms[nodeName] = temp;
            rooms[nodeName].setNodeName(nodeName);
         }

         numLines++;
         iss.clear();
      }
   }   

   ifstream nextstream;
   nextstream.open(filename.c_str());
   numLines = 1;
   skipBlanks = 1;

   cout << endl;

   while(getline(nextstream, line))
   {
      if(line.empty() || line.length() < 2)
      {}
      else
      {
         istringstream iss(line);

         if(numLines == 1)
            skipBlanks++;
         if(numLines == 2)
            skipBlanks++;
         if(numLines == 3)
            skipBlanks++;

         if(numLines > 3 && skipBlanks > 3)
         {
            string thisNode = line.substr(0,2);

            int first = line.find(" ", 0);
            int second = line.find(" ", first + 1);
            int third = line.find(" ", second + 1);
            int fourth = line.find(" ", third + 1);

            string firstNode = line.substr(first+1,2);
            string secondNode = line.substr(second+1,2);
            string thirdNode = line.substr(third+1,2);
            string fourthNode = line.substr(fourth+1,2);

            cout << "Line contains: " << line << endl;
            cout << "Current Node: " << thisNode << endl;
            cout << "firstNode:  -" << firstNode << endl;
            cout << "secondNode: -" << secondNode << endl;
            cout << "thirdNode:  -" << thirdNode << endl;
            cout << "fourthNode: -" << fourthNode << endl << endl;

            for(map<string,Node>::iterator thing = rooms.begin(); thing != rooms.end(); thing++)
            {
               if(thing->second.getNodeName() == rooms[thisNode].getNodeName())
               {
                  if(firstNode != "* " && firstNode != " *" && firstNode != "*")
                     thing->second.attachNewNode(&rooms[firstNode],1);
                  else
                  {
                     thing->second.attachNewNode(&empt,1);
                  }
                  if(secondNode != "* " && secondNode != " *" && secondNode != "*")
                     thing->second.attachNewNode(&rooms[secondNode],2);
                  else
                  {
                     thing->second.attachNewNode(&empt,2);
                  }
                  if(thirdNode != "* " && thirdNode != " *" && thirdNode != "*")
                     thing->second.attachNewNode(&rooms[thirdNode],3);
                  else
                  {
                     thing->second.attachNewNode(&empt,3);
                  }
                  if(fourthNode != "* " && fourthNode != " *" && fourthNode != "*")
                     thing->second.attachNewNode(&rooms[fourthNode],4);
                  else
                  {
                     thing->second.attachNewNode(&empt,4);
                  }
               }
            }
         }

         numLines++;
         iss.clear();
      }
   }
   cout << "Exiting buildGraph()" << endl << endl;
}

string System::getFileName()
{
   string filename;

   cout << "Enter the name of the Maze configuration file: ";
   cin >> filename;
   cout << endl;

   return filename + ".txt";
}

string System::getPath()
{
   string path;
   stack<string> pathNodes;
   string currentNode = startNode.getNodeName();

   cout << "added startNode" << endl;
   pathNodes.push(startNode.getNodeName());

   while(currentNode != endNode.getNodeName())
   {
      if(canMove(currentNode))
      {
         currentNode = move(currentNode);
         pathNodes.push(rooms[currentNode].getNodeName());
      }
      else
      {
         while(!canMove(currentNode))
         {
            pathNodes.pop();
            currentNode = pathNodes.top();
         }
      }
   }

   for(int i = 0; i < pathNodes.size(); i++)
   {
      path += pathNodes.top() + " ";
      pathNodes.pop();
   }

   return path;
}

void System::printMap(map<string,Node> nodes)
{
   cout << endl << "The nodes in the current map are:" << endl;
   for(map<string,Node>::iterator it = nodes.begin(); it != nodes.end(); it++)
   {
      cout << "current node: " << it->second.getNodeName() << endl;
      if(it->second.getAttachedNode(1)->getNodeName().length() < 3)
         cout << it->second.getAttachedNode(1)->getNodeName() << endl;
      if(it->second.getAttachedNode(2)->getNodeName().length() < 3)
         cout << it->second.getAttachedNode(2)->getNodeName() << endl;
      if(it->second.getAttachedNode(3)->getNodeName().length() < 3)
         cout << it->second.getAttachedNode(3)->getNodeName() << endl;
      if(it->second.getAttachedNode(4)->getNodeName().length() <  3)
         cout << it->second.getAttachedNode(4)->getNodeName() << endl;
   }
   cout << endl;

   cout << "Exited for in printMap." << endl << endl;
}

bool System::canMove(string currentNode)
{
   if(!rooms[currentNode].getAttachedNode(1)->visited ||\
      !rooms[currentNode].getAttachedNode(2)->visited ||\
      !rooms[currentNode].getAttachedNode(3)->visited ||\
      !rooms[currentNode].getAttachedNode(4)->visited)
         return true;

   return false;
}

string System::move(string currentNode)
{
   string newSpot;

   if(!rooms[currentNode].getAttachedNode(1)->visited)
      newSpot = rooms[currentNode].getAttachedNode(1)->getNodeName();
   if(!rooms[currentNode].getAttachedNode(2)->visited)
      newSpot = rooms[currentNode].getAttachedNode(2)->getNodeName();
   if(!rooms[currentNode].getAttachedNode(3)->visited)
      newSpot = rooms[currentNode].getAttachedNode(3)->getNodeName();
   if(!rooms[currentNode].getAttachedNode(4)->visited)
      newSpot = rooms[currentNode].getAttachedNode(4)->getNodeName();

   return newSpot;
}

然而,今天编译和执行main:

main ()
{
   System system;
   system.displayWelcome();
   string file;

   while(1)
   {
      file = system.getFileName();

      if(file == "Quit.txt" || file == "quit.txt")
         break;


      system.buildGraph(file);

      cout << "Made it through buildGraph()" << endl;


      system.printMap(system.rooms);
      string path = system.getPath();

      cout << "The Start Node is: " << system.startNode.getNodeName() << endl;
      cout << "The Destination Node is: " << system.endNode.getNodeName() << endl;
      cout << "Finding a path from the Start to the Destination node ... " << endl;

      if(path.length() > 1)
      {
         cout << "Congratulations: Found path successfully." << endl;
         cout << "The path is: " << path << endl;
      }
      else
         cout << "Unsuccessful: No path can be found." << endl;
   }

   system.displayExit();
}

我收到以下输出。

========================================================
|      Welcome to the Automatic Maze Path Finder!      |
========================================================

Enter the name of the Maze configuration file: maze1


Line contains: A1 A2 B1 * * 
Current Node: A1
firstNode:  -A2
secondNode: -B1
thirdNode:  -* 
fourthNode: -* 

Line contains: B1 B2 * * A1 
Current Node: B1
firstNode:  -B2
secondNode: -* 
thirdNode:  -* 
fourthNode: -A1

Line contains: C1 C2 * * * 
Current Node: C1
firstNode:  -C2
secondNode: -* 
thirdNode:  -* 
fourthNode: -* 

Line contains: D1 D2 E1 * * 
Current Node: D1
firstNode:  -D2
secondNode: -E1
thirdNode:  -* 
fourthNode: -* 

Line contains: E1 * * * D1 
Current Node: E1
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -D1

Line contains: F1 F2 * * * 
Current Node: F1
firstNode:  -F2
secondNode: -* 
thirdNode:  -* 
fourthNode: -* 

Line contains: G1 G2 H1 * * 
Current Node: G1
firstNode:  -G2
secondNode: -H1
thirdNode:  -* 
fourthNode: -* 

Line contains: H1 * * * G1 
Current Node: H1
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -G1

Line contains: A2 A3 * A1 * 
Current Node: A2
firstNode:  -A3
secondNode: -* 
thirdNode:  -A1
fourthNode: -* 

Line contains: B2 * C2 B1 * 
Current Node: B2
firstNode:  -* 
secondNode: -C2
thirdNode:  -B1
fourthNode: -* 

Line contains: C2 * D2 C1 B2 
Current Node: C2
firstNode:  -* 
secondNode: -D2
thirdNode:  -C1
fourthNode: -B2

Line contains: D2 D3 * D1 C2 
Current Node: D2
firstNode:  -D3
secondNode: -* 
thirdNode:  -D1
fourthNode: -C2

Line contains: E2 E3 * * * 
Current Node: E2
firstNode:  -E3
secondNode: -* 
thirdNode:  -* 
fourthNode: -* 

Line contains: F2 F3 G2 F1 * 
Current Node: F2
firstNode:  -F3
secondNode: -G2
thirdNode:  -F1
fourthNode: -* 

Line contains: G2 * H2 G1 F2 
Current Node: G2
firstNode:  -* 
secondNode: -H2
thirdNode:  -G1
fourthNode: -F2

Line contains: H2 H3 * * G2 
Current Node: H2
firstNode:  -H3
secondNode: -* 
thirdNode:  -* 
fourthNode: -G2

Line contains: A3 * B3 A2 * 
Current Node: A3
firstNode:  -* 
secondNode: -B3
thirdNode:  -A2
fourthNode: -* 

Line contains: B3 B4 * * A3 
Current Node: B3
firstNode:  -B4
secondNode: -* 
thirdNode:  -* 
fourthNode: -A3

Line contains: C3 C4 D3 * * 
Current Node: C3
firstNode:  -C4
secondNode: -D3
thirdNode:  -* 
fourthNode: -* 

Line contains: D3 * E3 D2 C3 
Current Node: D3
firstNode:  -* 
secondNode: -E3
thirdNode:  -D2
fourthNode: -C3

Line contains: E3 * * E2 D3 
Current Node: E3
firstNode:  -* 
secondNode: -* 
thirdNode:  -E2
fourthNode: -D3

Line contains: F3 F4 * F2 * 
Current Node: F3
firstNode:  -F4
secondNode: -* 
thirdNode:  -F2
fourthNode: -* 

Line contains: G3 G4 * * * 
Current Node: G3
firstNode:  -G4
secondNode: -* 
thirdNode:  -* 
fourthNode: -* 

Line contains: H3 H4 * H2 * 
Current Node: H3
firstNode:  -H4
secondNode: -* 
thirdNode:  -H2
fourthNode: -* 

Line contains: A4 A5 B4 * * 
Current Node: A4
firstNode:  -A5
secondNode: -B4
thirdNode:  -* 
fourthNode: -* 

Line contains: B4 B5 * B3 A4 
Current Node: B4
firstNode:  -B5
secondNode: -* 
thirdNode:  -B3
fourthNode: -A4

Line contains: C4 * D4 C3 * 
Current Node: C4
firstNode:  -* 
secondNode: -D4
thirdNode:  -C3
fourthNode: -* 

Line contains: D4 * E4 * C4 
Current Node: D4
firstNode:  -* 
secondNode: -E4
thirdNode:  -* 
fourthNode: -C4

Line contains: E4 E5 F4 * D4 
Current Node: E4
firstNode:  -E5
secondNode: -F4
thirdNode:  -* 
fourthNode: -D4

Line contains: F4 * G4 F3 E4 
Current Node: F4
firstNode:  -* 
secondNode: -G4
thirdNode:  -F3
fourthNode: -E4

Line contains: G4 * * G3 F4 
Current Node: G4
firstNode:  -* 
secondNode: -* 
thirdNode:  -G3
fourthNode: -F4

Line contains: H4 H5 * H3 * 
Current Node: H4
firstNode:  -H5
secondNode: -* 
thirdNode:  -H3
fourthNode: -* 

Line contains: A5 A6 * A4 * 
Current Node: A5
firstNode:  -A6
secondNode: -* 
thirdNode:  -A4
fourthNode: -* 

Line contains: B5 * C5 B4 * 
Current Node: B5
firstNode:  -* 
secondNode: -C5
thirdNode:  -B4
fourthNode: -* 

Line contains: C5 C6 D5 * B5 
Current Node: C5
firstNode:  -C6
secondNode: -D5
thirdNode:  -* 
fourthNode: -B5

Line contains: D5 * * * C5 
Current Node: D5
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -C5

Line contains: E5 E6 F5 E4 * 
Current Node: E5
firstNode:  -E6
secondNode: -F5
thirdNode:  -E4
fourthNode: -* 

Line contains: F5 * * * E5 
Current Node: F5
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -E5

Line contains: G5 G6 H5 * * 
Current Node: G5
firstNode:  -G6
secondNode: -H5
thirdNode:  -* 
fourthNode: -* 

Line contains: H5 * * H4 G5 
Current Node: H5
firstNode:  -* 
secondNode: -* 
thirdNode:  -H4
fourthNode: -G5

Line contains: A6 * B6 A5 * 
Current Node: A6
firstNode:  -* 
secondNode: -B6
thirdNode:  -A5
fourthNode: -* 

Line contains: B6 * * * A6 
Current Node: B6
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -A6

Line contains: C6 * * C5 * 
Current Node: C6
firstNode:  -* 
secondNode: -* 
thirdNode:  -C5
fourthNode: -* 

Line contains: D6 * E6 * * 
Current Node: D6
firstNode:  -* 
secondNode: -E6
thirdNode:  -* 
fourthNode: -* 

Line contains: E6 * F6 E5 D6 
Current Node: E6
firstNode:  -* 
secondNode: -F6
thirdNode:  -E5
fourthNode: -D6

Line contains: F6 * * * E6 
Current Node: F6
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -E6

Line contains: G6 * H6 G5 * 
Current Node: G6
firstNode:  -* 
secondNode: -H6
thirdNode:  -G5
fourthNode: -* 

Line contains: H6 * * * G6 
Current Node: H6
firstNode:  -* 
secondNode: -* 
thirdNode:  -* 
fourthNode: -G6

Exiting buildGraph()

*** Error in `./lab03.out': free(): invalid size: 0x000000000106ca80 ***
Aborted (core dumped)

最后两行之前的所有内容都符合预期,您可以看到这些行似乎已被正确读取和处理。请注意,buildGraph()函数末尾的print语句已成功打印,但main()中紧跟其后的下一个print语句却没有。可能导致此问题的原因是什么?我该如何解决这个问题呢?感谢。

1 个答案:

答案 0 :(得分:1)

你不能这样做:

{
    Node empt;
    empt.setNodeName("null");
    thing->second.attachNewNode(&empt,1);
}

empt是一个局部变量,在块完成后会被销毁,所以你有悬空指针。将容器中的未命名节点保存在某个功能(具有适当的生命周期)的可能解决方案之一并添加它们:

{
    unnamedNodes.emplace_back( "null" );
    thing.second.attachNeNode( &unnamedNodes.back(), 1 );
}

并定义:

std::list<Node> unnamedNodes;

在你班上。您可以使用std::vector代替,但必须确保不会发生重新分配(提前预留足够的大小)