分段错误错误?

时间:2017-11-22 06:10:40

标签: c++ c++11 segmentation-fault nodes

在测试我的getStartNode()和getEndNode()函数时,我一直收到分段错误错误。当我使用带有字符串文字作为参数的search()函数分配startNode / endNode时它工作正常,但是当我使用由于某种原因分配了name本身的字符串时,它没有给我一个分段错误。 问题行出现在generateGraph(字符串文件)函数中。

我的问题是,为什么它可以使用字符串文字,而不是使用与文字本身分配相同值的字符串?

编译: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 << "\n\t*** 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 * *

1 个答案:

答案 0 :(得分:1)

使用getline获取单个字时,您需要删除尾随换行符。

您实际上没有按预期阅读"A1",而是"A1\n"