我有一个我似乎无法弄清楚的问题。下面是我的所有代码,详细说明了两个类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语句却没有。可能导致此问题的原因是什么?我该如何解决这个问题呢?感谢。
答案 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
代替,但必须确保不会发生重新分配(提前预留足够的大小)