Search code examples
c++depth-first-search

Segmentation fault in implementating DFS in C++


I have an implementation of graph traversal in C++. I tried to debug and fix it but it didn't work. It seems my program crashed because there's something wrong with my adjacent list in the graph and I tried to access the memory that I haven't initialized. Can you guys help me? Thanks in advance.

Graph.h

#ifndef GRAPH_H
#define GRAPH_H

#include <list>
#include <vector>

class Graph {
    int vertex;
    bool isDirected;
    std::vector<std::list<int>> adjList;
public:
    Graph(int vertex = 10, bool isDirected = false)
        : vertex(vertex), isDirected(isDirected) {
        adjList.resize(vertex);
    }
    void addEdge(int src, int dest) {
        adjList[src].push_back(dest);
        if (!isDirected) adjList[dest].push_back(src);
    }

    int getVertex() const { return this->vertex; }
    std::vector<std::list<int>> getAdjList() const { return this->adjList; }
};

#endif /* GRAPH_H */

Traverse.h

#ifndef TRAVERSE_H
#define TRAVERSE_H

#include "Graph.h"
#include <deque>
#include <iostream>

class Traverse {
    std::deque<bool> visited;
public:
    Traverse(Graph graph) { visited.assign(graph.getVertex(), false); }
    void DFS(Graph graph, int parentVertex) {
        visited[parentVertex] = true;
        std::cout << parentVertex << std::endl;

        // Segmentation fault here
        for (auto childVertex : graph.getAdjList().at(parentVertex))
            if (visited.at(childVertex) == false) DFS(graph, childVertex);
    }
};
#endif /* TRAVERSE_H */

graph.cpp

#include <iostream>
#include "Graph.h"
#include "Traverse.h"
int main(int argc, char **argv) {
    Graph graph(5, true);
    graph.addEdge(1, 2);
    graph.addEdge(1, 3);
    graph.addEdge(2, 3);
    graph.addEdge(1, 4);

    Traverse traverse(graph);
    traverse.DFS(graph, 1);

    return EXIT_SUCCESS;
}

Solution

  • As the comment stated, you are returning copies of the adjacency list instead of the actual adjacency list. That becomes an issue here:

    for (auto childVertex : graph.getAdjList().at(parentVertex))

    Since a local copy is returned, the iterator becomes invalid when iterating to the next element.

    One fix is to change your getAdjList() function to return a reference:

    std::vector<std::list<int>>& getAdjList() { return this->adjList; }