分割故障错误

Segmentation fault error?

本文关键字:错误 故障 分割      更新时间:2023-10-16

我在测试我的getstartnode()和getendNode()函数时不断遇到分割故障错误。当我使用search()函数将字符串文字作为参数分配启动节点/endnode时,它可以正常工作,但是当我出于某种原因使用名称分配的字符串时,它却不能,这给了我一个分割错误。问题行发生在GenerateGraph(String File)函数中。

我的问题是,为什么它可以与字符串文字合作,而不能与具有与文字本身相同的值分配的字符串?

编译:g -std = c 11 main.cpp node.h node.cpp graph.h graph.cpp

运行:./a.out Samplegraph.txt

main.cpp

#include <iostream>
#include <fstream>
#include <string>
//#include "Banner.h"
//#include "Player.h"
#include "Graph.h"
#include "Node.h"
using namespace std;

int main(int argc, char *argv[])
{
    string file = argv[1];
    cout << file << endl;
    Graph maze;
    maze.generateGraph(file);
    // Welcome banner for start of game
    //Banner welcome("Welcome to the Snakes and Ladders Maze Game");
    //cout << welcome.getBanner() << endl;
    // Testing
    cout << maze.getNumberOfNodes() << endl;
    cout << maze.getNodeList()[47].getNodeName() << endl;
    cout << maze.getNodeList()[4].getAttachedNode(0)->getNodeName() << endl;
    cout << maze.getStartNode()->getNodeName() << endl;
    cout << maze.getEndNode()->getNodeName() << endl;
    return 0;
}

node.h

#ifndef NODE_H
#define NODE_H
#include <string>
class Node 
{
    public:
        Node();
        Node(std::string newname);
        void setNodeName(std::string newname);
        std::string getNodeName();
        void attachNewNode(Node *newNode, int direction);
        Node *getAttachedNode(int direction);
        void attachSnakeLadderNode(Node *newNode);
        Node *getSnakeLadderNode();
    private:
        std::string name; // Name of Node
        Node *attachedNodes[4];
        Node *snakeOrLadderNodes;
};
#endif // NODE_H

node.cpp

#include "Node.h"
using namespace std;
//enum Direction {N, E, S, W};
// Constructors
Node::Node()
{
}
Node::Node(string newname)
{
    name = newname;
}
// Function:    setNodeName
// Inputs:  string newname
// Outputs: void
// Description: Assigns name of Node to newname
void Node::setNodeName(string newname)
{
    name = newname;
}
// Function:    getNodeName
// Inputs:  None
// Outputs: string
// Description: Returns the Nodes name.
string Node::getNodeName()
{
    return name;
}
// Function:    attachNewNode
// Inputs:  Node *newNode, int direction
// Outputs: void
// Description: Attaches a new node with a specific direction.
void Node::attachNewNode(Node *newNode, int direction)
{
    attachedNodes[direction] = newNode;
}
// Function:    *getAttachedNode
// Inputs:  int direction
// Outputs: Node
// Description: Returns the Node located at specified direction.
Node *Node::getAttachedNode(int direction)
{
    return attachedNodes[direction];
}
// Function:    attachSnakeLadderNode
// Inputs:  Node *newNode
// Outputs: void
// Description: Attaches snake/ladder Node
void Node::attachSnakeLadderNode(Node *newNode)
{
    snakeOrLadderNodes = newNode;
}
// Function:    *getSnakeLadderNode
// Inputs:  None
// Outputs: Node
// Description: Returns snake/ladder Node.
Node *Node::getSnakeLadderNode()
{
    return snakeOrLadderNodes;
}

Graph.h

#ifndef GRAPH_H
#define GRAPH_H
#include <fstream>
#include <sstream>
#include <vector>
#include "Node.h"
class Graph
{
    public:
        Graph();
        void setNumberOfNodes(int num);
        int getNumberOfNodes();
        void setNodeList(int num);
        Node *getNodeList();
        Node *search(std::string target);
        void setStartNode(Node *newNode);
        Node *getStartNode();
        void setEndNode(Node *newNode);
        Node *getEndNode();
        void generateGraph(std::string file);
    private:
        int numOfNodes;
        Node *nodeList;
        Node *startNode;
        Node *endNode;
};
#endif // GRAPH_H

graph.cpp

#include "Graph.h"
#include <iostream>
#include <cstdlib>
using namespace std;
// Constructor
Graph::Graph()
{
}
// Function:    setNumberofNodes
// Inputs:  int num
// Outputs: void
// Description: Sets the number of Nodes
void Graph::setNumberOfNodes(int num)
{
    numOfNodes = num;
}
// Function:    getNumberOfNodes
// Inputs:  None
// Outputs: int
// Description: Return number of Nodes.
int Graph::getNumberOfNodes()
{
    return numOfNodes;
}
// Function: setNodeList
// Inputs:  int numOfNodes
// Outputs: void
// Description: Sets the Node list with size of numOfNodes.
void Graph::setNodeList(int num)
{
    nodeList = new Node[num];
}
// Function: getNodeList
// Inputs:  None
// Outputs: nodeList
// Description: Returns pointer to array of nodes
Node *Graph::getNodeList()
{
    return nodeList;
}
// Function:    search
// Inputs:  string name of node target
// Outputs: Pointer to found node
// Description: Returns pointer of the targeted node.
Node *Graph::search(string target)
{
    for (int i = 0; i < numOfNodes; i++)
    {
            if (nodeList[i].getNodeName() == target)
            {
                return &nodeList[i];
            }
    }
}
void Graph::setStartNode(Node *newNode)
{
    startNode = newNode;
}
// Function:    getStartNode
// Inputs:  None
// Outputs: Node *startNode
// Description: Returns pointer to starting node.
Node *Graph::getStartNode()
{
    return startNode;
}
void Graph::setEndNode(Node *newNode)
{
    endNode = newNode;
}
// Function:    getEndNode
// Inputs:  None
// Outputs: Node *endNode
// Description: Returns pointer to destination node.
Node *Graph::getEndNode()
{
    return endNode;
}
// Function: generateGraph
// Inputs:
// Outputs:
// Description:
void Graph::generateGraph(string inFile)
{
    ifstream fin;
    fin.open(inFile);
    if (!fin.fail())
    {
        vector<string> rows;
        string row;
        // First Line (Number of Nodes)
        string numberOfNodes;
        getline(fin, numberOfNodes);
        setNumberOfNodes(stoi(numberOfNodes));
        setNodeList(numOfNodes);
        // Second Line (Start Node)
        string startNodeName;
        getline(fin, startNodeName);
        // Third Line (Destination Node)
        string endNodeName;
        getline(fin, endNodeName);
        // Fourth-Last Lines (Graph)
        while (!fin.eof()) // Scans remaining rows of file and adds each line to a vector<string>
        {
            getline(fin, row);
            rows.push_back(row);
        }
        fin.close();
        // Reads the first column, creates Node objects with names and adds it to the node list
        for (int i = 0; i < numOfNodes; i++)
        {
            string nodeName;
            istringstream iss(rows[i]);
            iss >> nodeName;
            nodeList[i] = Node(nodeName);
        } // end loop
        // Assign start/end nodes
        cout << "Start node: " << startNodeName << endl; 
        setStartNode(search(startNodeName)); // Problem, should be A1
        // setStartNode(search("A1")); // Works, but start node can change.
        setEndNode(search(endNodeName)); // Problem, should be H6
        // setEndNode(search("H6")); //Works, but end node can change.
        // Reads lines stored in vector<string> and links each node
        string info;
        string north, east, south, west, snake_ladder;
        for (int i = 0; i < numOfNodes; i++)
        {
            info = rows[i].substr(rows[i].find(" ") + 1, string::npos);
            istringstream iss(info);
            iss >> north >> east >> south >> west >> snake_ladder;
            // Link North Node
            if (north == "*")
            {
                nodeList[i].attachNewNode(NULL, 0);
            }
            else
            {
                nodeList[i].attachNewNode(search(north), 0);
            }
            // Link East Node
            if (east == "*")
            {
                nodeList[i].attachNewNode(NULL, 1);
            }
            else
            {
                nodeList[i].attachNewNode(search(east), 1);
            }
            // Link South Node
            if (south == "*")
            {
                nodeList[i].attachNewNode(NULL, 2);
            }
            else
            {
                nodeList[i].attachNewNode(search(south), 2);
            }
            // Link West Node
            if (west == "*")
            {
                nodeList[i].attachNewNode(NULL, 3);
            }
            else
            {
                nodeList[i].attachNewNode(search(west), 3);
            }
            // Link Snake/Ladder Node
            if (snake_ladder == "*")
            {
                nodeList[i].attachSnakeLadderNode(NULL);
            }
            else
            {
                nodeList[i].attachSnakeLadderNode(search(snake_ladder));
            }
        } // end loop
    }
    else
    {
        cerr << "nt*** ERROR: File failed to open, program terminating! ***n" << endl;
        exit(0);
    }
}

samplegraph.txt

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

使用 getline获取单个单词时,您需要剥离尾线。

您实际上没有按照预期的方式读取"A1",但是"A1n"