jason adams
jason adams

Reputation: 565

Different results when running in LLVM and gcc

A few days ago, a script that ran on my laptop ran differently than running it on another Linux box (the scripts I ran are identical to each other). My guess is that my compiler is missing something. I don't know what the problem is though.

After running g++ -v, this is the result I get:

Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

After running g++ -v on this other Linux box, I'm getting:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.3/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.3-20140911/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.3-20140911/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) 

The following script is a script to calculate shortest path to all vertices from one source vertex, in this case it's vertex 1. The output of this script lists every single vertex and its shortest distance to it from the source. The input file in question is also listed below. Here's my script in question:

#include <iostream>
#include <sstream>
#include <fstream>
#include <list>
#include <limits>

using namespace std;

struct Node{
    int dist;
    int v;

    bool operator==(const Node& a){
        return dist == a.dist;
    }

    bool operator!=(const Node& a){
        return (!(dist  == a.dist));
    }

    bool operator<(const Node& a){
        return dist < a.dist;
    }
    bool operator>(const Node& a){
        return a.dist < dist;
    }
    int operator+(const Node& a){
        return a.dist+dist;
    }
};

struct cheapHeap{
    int curSize;
    Node * minHeap;
};

class DijkstraSolution{

    private:
        int size;
        int sourceV;
        list<Node> *container; //this is the container to hold input data
        int *results;          //this is the array to hold final results
        cheapHeap ch;          //this is the array that holds each dist looked at

    public:
        DijkstraSolution(string fname, int inSourceV, int inSize): size(inSize), sourceV(inSourceV){

            //read the file and initialize the list<Node> container
            container = new list<Node>[size];

            ifstream infile;
            infile.open(fname.c_str());
            string line = "";

            if (infile){
                while (getline(infile, line)){
                    istringstream iss(line);
                    int vertex;
                    int v;
                    int dist;
                    iss >> vertex;
                    while(iss >> v >> dist){
                        Node edges;
                        edges.dist = dist;
                        edges.v = v;
                        container[vertex].push_back(edges);
                    }
                }
            }
            infile.close();

            //initialization of results and minHeap array
            int maxVal = numeric_limits<int>::max();
            results = new int[size];

            ch.curSize = size-1; 
            ch.minHeap = new Node[size];

            for (int i = 0; i < size; i++){
                results[i] = maxVal;
                ch.minHeap[i].dist = maxVal;
            }
            results[sourceV] = 0;
            ch.minHeap[sourceV].dist = 0;
            ch.minHeap[sourceV].v = sourceV;

        }

        //find min of all nodes inserted into minHeap
        Node findMin(){
            Node minimum;
            minimum.dist = numeric_limits<int>::max();
            minimum.v = 0;

            for (int i=1; i <= size; i++){
                if ((ch.minHeap[i] < minimum) && (ch.minHeap[i].dist != -1)){
                    minimum = ch.minHeap[i];

                }
            }
            ch.minHeap[minimum.v].dist = -1;
            ch.curSize--;
            return minimum;
        }

        //for every min that findMin() spits out, insert this min into the results array 
        int * dijkstra(){
            while (ch.curSize != 0){
                Node minimum = findMin(); 
                results[minimum.v] = minimum.dist; 

                for (list<Node>::iterator it = container[minimum.v].begin(); it != container[minimum.v].end(); it++){
                    if ((*it)+minimum < ch.minHeap[(*it).v].dist){
                        Node inserted;
                        inserted.dist = *it + minimum;
                        inserted.v = (*it).v;
                        ch.minHeap[(*it).v] = inserted;

                    }
                }
            }
            return results;
        }

        //this prints the contents from the file input
        void printContainer(){
            for (int i=1; i < size; i++){
                cout << i << " ";
                list<Node>::iterator iter;
                for (iter = container[i].begin(); iter != container[i].end(); iter++){
                    cout << iter -> v << " " << iter -> dist << " ";
                }
                cout <<endl;
            }
        }

        //this prints out the contents from the results array   
        void printResults(){
            for (int i = 1; i < size; i++){
                cout << i << " -> " << results[i] << endl;
            }
        }
};

int main(){

    DijkstraSolution ds("pa5_test1.txt", 1, 9);

    ds.dijkstra(); 
    ds.printResults();

}

This is my input file:

1   2 1 8 2
2   1 1 3 1
3   2 1 4 1
4   3 1 5 1
5   4 1 6 1
6   5 1 7 1
7   6 1 8 1
8   7 1 1 2

This is the output I'm getting from my Mac, which is incorrect:

1 -> 0
2 -> 2147483647
3 -> 2147483647
4 -> 2147483647
5 -> 2147483647
6 -> 2147483647
7 -> 2147483647
8 -> 2147483647

This is the output I'm getting from the other Linux box, which is correct:

1 -> 0
2 -> 1
3 -> 2
4 -> 3
5 -> 4
6 -> 4
7 -> 3
8 -> 2

Apparently, my compiler is not updating the results array. Apparently, it updates the first entry to 0, and then it just stops updating it. This is really strange because I've run the same exact code on different boxes and the results are the same as the Linux box, so I'm guessing it's my compiler. What is frustrating is that I'm not getting any errors, so I don't even know where to begin looking for an answer. Also, not sure if this is related, but when I fire up gdb, it doesn't debug a script that is written as a class. It only debugs code that has a main and functions, it trips when I write a main function that instantiates some class. If my compiler is indeed broken, any suggestions (baby steps) as to how to rebuild it? Sorry for the long post.

Upvotes: 0

Views: 228

Answers (1)

PaulMcKenzie
PaulMcKenzie

Reputation: 35440

One issue is this:

    for (int i=1; i <= size; i++){  // <-- Index goes out of bounds here
        if ((ch.minHeap[i] < minimum) && (ch.minHeap[i].dist != -1)){
            minimum = ch.minHeap[i];

You are looping to size, but minHeap[size] is an out-of-bounds access.

Upvotes: 2

Related Questions