0

Origin

I was trying to build a graph data structure and I want to use a .txt file to initialize the graph. The first time it runs successfully. But after I added another DAG.txt file, exception happened.

Information

  • OS: Windows 10
  • Develop Environment: VS Code with Git, CMake and MinGW64.

The file organization:

D:.
├───.vscode
├───build
│   ├───.cmake
│   │   └───api
│   │       └───v1
│   │           ├───query
│   │           │   └───client-vscode
│   │           └───reply
│   ├───bin(.dll and .exe file)
│   ├───CMakeFiles
│   │   ├───3.19.2
│   │   │   ├───CompilerIdC
│   │   │   │   └───tmp
│   │   │   └───CompilerIdCXX
│   │   │       └───tmp
│   │   ├───CMakeTmp
│   │   ├───Graph_Algorithm.dir
│   │   │   └───src
│   │   └───Main.dir
│   └───Testing
│       ├───20210421-1414
│       └───Temporary
├───include(.hpp file)
├───rsrc(Including .txt file)
└───src
(Main.cpp, CMakeLists.txt etc)

Details

UGraph is a class template. I use a char array to initialize the vertex vector Vertex and a Edge.txt to initialize the adjacency matrix Edge. The Edge.txt was written in this format:

0 1 1
0 1 2
0 2 3
2 1 3

1 2 1
4 1 1

Vertex1-Weight-Vertex2.

The constructor:

template<typename Tp>
UGraph<Tp>::UGraph(const Tp arr[], size_t num, std::ifstream& edge, Mode mode) : Vertex(arr, arr + num), size(num)
{
    // Allocate memory
    Edge = new double*[MAX];
    for (size_t i = 0; i < MAX; i++){
        Edge[i] = new double[10];
        for (size_t j = 0; j < MAX; j++){
            if(i == j)
                Edge[i][j] = 0;
            else
                Edge[i][j] = Infinity;
        }
    }

    // TODO Get edge data and connect the vertecies
    if (!edge || edge.eof()){
        throw "Initial file is invalid.";
    }
 
    while(!edge.eof()){
        double weight;
        size_t i, j;// Vertecies indecies
        edge >> i;
        edge >> weight;
        edge >> j;

        // Watch
        cout << i << ' ' << weight << ' ' << j << endl;

        if (i > size - 1 || j > size - 1) { throw "Index overflow at constructor."; }
        switch (mode)
        {
        case Mode::UN_DIRECTED:
            Edge[j][i] = weight;
        case Mode::DIRECTED:
            Edge[i][j] = weight;
        default:
            break;
        }
    }

    edge.close();

    // //Test
    // for (size_t i = 0; i < size; i++){
    //     for (size_t j = 0; j < size; j++){
    //         if(Edge[i][j] != Infinity){
    //             cout << Edge[i][j] << ' ';
    //         }else{
    //             cout << "INF" << ' ';
    //         }
    //     }
    //     cout << endl;
    // }
    
}

The CMakeLists.txt:

cmake_minimum_required(VERSION 3.1.0)
project(Graph_Algorithm)

# Collect file
aux_source_directory(./src SRC)
include_directories(./include)

set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# Generate lib
add_library(Graph_Algorithm SHARED ${SRC} ${PROJECT_SOURCE_DIR}/include/UGraph.hpp)

# Header file
target_include_directories(Graph_Algorithm
PUBLIC 
./include)

# Compile
add_executable(Main main.cpp)

# Link
target_link_libraries(Main Graph_Algorithm)

The Main.cpp:

#include "UGraph.hpp"

int main(){
    try{
        std::ifstream file("./../../rsrc/DAG.txt");
        char s[]{"ABCDEFGHIJKMLNOPQRSTU"};
        UGraph<char> ug(s, 14, file, UGraph<char>::Mode::DIRECTED);
        std::vector<size_t> vec;
        ug.BreadthFirstTraverse(0);
        // ug.DepthFirstTraverse();
        ug.Prim();
        cout << endl;
        ug.Kruskal();
        ug.Dijstra(3, vec);
        
    }
    catch(const std::exception& e){
        std::cerr << e.what() << '\n';
    }
    catch(const char* msg){
        std::cerr << "ErrorFound: " << msg << std::endl;
    }
    
    return 0;
}

The class UGraph:

const double Infinity{99999.9};

template<typename Tp>
class UGraph
{
private:
    std::vector<Tp> Vertex;
    // Adjacent Matrix, Row is out, Colum is in.
    double ** Edge;
    size_t size;

public:
    static const unsigned int MAX{10};
    enum class Mode { DIRECTED, UN_DIRECTED };

    UGraph();
    UGraph(const Tp arr[], size_t num, std::ifstream& edge, Mode mode = Mode::UN_DIRECTED);
    ~UGraph();
    double*& operator[](size_t i) { 
        if (i > size - 1){
            throw "Index Overflow at [] operator.";
        }
        return Edge[i]; 
    }
    auto BreadthFirstTraverse(size_t root);
    void DepthFirstTraverse();
    void DFS(size_t root, std::vector<bool>& Visited);
    void Prim();
    void Kruskal();
    void Dijstra(size_t v1, std::vector<size_t>& shortestWay);
    // void Floyd();
};

Exceptions

If using CMake Launch, it reads some of lines then aborts, shows nothing;

if using cmd or powershell launch, it shows "Initial file is invaild.";

if using gdb, it shows the same massage as powershell.

  • This program once worked smoothly. The exceptions happened when another initial file was used.

All the message are contained in exception objects (Most of them are strings), which will be catched by int main() them be showed in stderr.

Xianyu
  • 1
  • 1
  • What is the value of `MAX`? You are doing `Edge[i] = new double[10];` and then immediately running a loop where you assign `MAX` elements to that array of 10 elements. – paddy Apr 23 '21 at 03:28
  • "it shows 'initial file is invalid'" -- WHO shows that? Your code doesn't print that any where here. – Tim Roberts Apr 23 '21 at 03:33
  • @TimRoberts Actually it does. After checking if the `ifstream` is ok. – super Apr 23 '21 at 03:34
  • `while (!edge.eof()) { ... }` is an issue. Read [this](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). As for cmd/powershell it most likely doesn't find the file. – super Apr 23 '21 at 03:38
  • My bad, you're right. The implication, then, is that the file is no longer located at the same relative location in all your example. – Tim Roberts Apr 23 '21 at 04:12
  • @paddy The second parameter `size_t num` of the constructor is the value of `MAX` ( I use `const size_t UGraph::size` replace `MAX` macro). – Xianyu Apr 24 '21 at 05:21
  • @TimRoberts The most weird thing is that the another file that located in the same folder can work successfully... – Xianyu Apr 24 '21 at 05:29

0 Answers0