lundi 27 novembre 2017

SegFault in the server, but not in my ide

I am writing a project for my class, and I have gotten it to work in my ide (Cloud9), but when I try to test it in the server for the class, I get a segmentation fault. Can someone tell me where it would be faulting/why it occurs on the server and not in my ide? This is my code:

#ifndef HEAP_H 
#define HEAP_H 
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class heap {
public:
    //creates a struct to hold the character, its frequency, its left and right pointers in the tree, and whether it was visited or not
    struct node {
        unsigned int c;
        int freq;
        node* left;
        node* right;
        bool visited;
    };

    //constructs the heap and tree (essentially does everything)
    heap(string origMessage, ofstream& preOrderOutput, ofstream& inOrderOutput, ofstream& codeOutput){ 
        //creates a string array to later hold the encoding of each character in the message
        string codeMessage[origMessage.length()];
        //sets heapSize
        heapSize = 0;
        //creates the beginning of my heap
        myHeap = new node[origMessage.length()];

        //puts all of the unique characters from orMessage into the heap
        for(unsigned int i = 0; i < origMessage.length(); i++){
            //orMessage[i] = origMessage.at(i);
            int location = find(myHeap, origMessage[i], heapSize);
            //creates an array holding all of the unique characters and their frequencies
            if(location < 0){
                myHeap[heapSize].c = origMessage[i];
                myHeap[heapSize].freq = 1;
                myHeap[heapSize].left = NULL;
                myHeap[heapSize].right = NULL;
                myHeap[heapSize].visited = false;
                heapSize++;
            } else {
                (myHeap[location].freq)++;
            }
        }
        origHeapSize = heapSize;
        //puts the heap in heap order
        fixOrder();
        while(heapSize > 1){
            extractMin();
            numArbs++;
        }

        findInTree();
        //prints the encoded message into code.txt
        for(unsigned int i = 0; i < origMessage.length(); i++){
            int letter = find(visited, origMessage[i], origHeapSize+numArbs); //here
            codeMessage[i] = encryptions[letter];
            codeOutput << codeMessage[i];
        }

        //prints inOrder and preOrder to their respective files
        inOrder(&myHeap[0], inOrderOutput);
        preOrder(&myHeap[0], preOrderOutput);
    }

    //prints the inOrder
    void inOrder(node* root, ofstream& inOrderOutput){
        if(root != NULL) {
            inOrder(root->left, inOrderOutput);
            inOrderOutput.put(root->c);
            inOrder(root->right, inOrderOutput);
        }
    }
    //prints the preOrder
    void preOrder(node* root, ofstream& preOrderOutput){
        if(root != NULL) {
            preOrderOutput.put(root->c);
            preOrder(root->left, preOrderOutput);
            preOrder(root->right, preOrderOutput);
        }
    }
    //saves all of the encryptions to an array the corresponds to an array of all of the values
    void findInTree() {
        string encryption = "";
        int numVisited = 1;
        node currNode = myHeap[0];
        visited = new node[origHeapSize+numArbs];
        encryptions = new string[origHeapSize+numArbs];
        visited[0] = currNode;
        encryptions[0] = "";
        //runs through the whole tree
        while(numVisited < origHeapSize+numArbs){
            //goes left as long as possible, saving the node and encryptions as it goes along
            while((currNode.left != NULL) && (!(currNode.left)->visited)){
                encryption += "0";
                visited[numVisited] = *(currNode.left);
                encryptions[numVisited] = encryption;
                (currNode.left)->visited = true;
                currNode = *(currNode.left);
                numVisited++;
            }

            int j = numVisited-2;
            //finds the next right node available that hasn't already been visited
            while((currNode.right == NULL) || ((currNode.right)->visited)){
                currNode = visited[j];
                encryption = encryptions[j];
                j--;
            }
            //saves that node and its encryption
            encryption += "1";
            visited[numVisited] = *(currNode.right);
            encryptions[numVisited] = encryption;
            (currNode.right)->visited = true;
            currNode = *(currNode.right);
            numVisited++;

        }
    }
    //fixes heap order for a max-ordered heap (I know it was supposed to be min-ordered, but I started with max-ordered, and it was too late to fix it, sorry)
    void fixOrder() {
        int numSwitches = 0;
        for(int i = 0; i < heapSize; i++){
            if(myHeap[i].freq>myHeap[(i-1)/2].freq){
                node temp = myHeap[i];
                myHeap[i] = myHeap[(i-1)/2];
                myHeap[(i-1)/2] = temp;
                numSwitches++;
            }
            if(numSwitches != 0){
                i--;
            }
        }
    }

    //builds the tree using a max-ordered heap (sorry)
    void extractMin() {
        int indexOfFirstMin = heapSize-1;
        //finds the first min
        for(int i = (heapSize-2); i >= (heapSize/2)-1; i--){
            if(myHeap[i].freq < myHeap[indexOfFirstMin].freq){
                indexOfFirstMin = i;
            }
        }
        //saves it
        node* tempLeft = new node;

        tempLeft->c = myHeap[indexOfFirstMin].c;
        tempLeft->freq = myHeap[indexOfFirstMin].freq;
        tempLeft->left = myHeap[indexOfFirstMin].left;
        tempLeft->right = myHeap[indexOfFirstMin].right;
        //gets rid of the min from the heap
        for(int i = indexOfFirstMin; i < heapSize-1; i++){
            myHeap[i] = myHeap[i+1];
        }
        heapSize--;
        //finds the second min
        int indexOfSecondMin = heapSize-1;
        if(heapSize != 1){
            for(int i = (heapSize-2); i >= (heapSize/2)-1; i--){
                if(myHeap[i].freq < myHeap[indexOfSecondMin].freq){
                    indexOfSecondMin = i;
                }
            }
        }
        //saves it
        node* tempRight = new node;

        tempRight->c = myHeap[indexOfSecondMin].c;
        tempRight->freq = myHeap[indexOfSecondMin].freq;
        tempRight->left = myHeap[indexOfSecondMin].left;
        tempRight->right = myHeap[indexOfSecondMin].right;
        //removes it from the heap
        for(int i = indexOfSecondMin; i < heapSize-1; i++){
            myHeap[i] = myHeap[i+1];
        }
        //changes the last node in the heap to the one created below using an arbitrary number as the data with pointers to the removed min nodes
        myHeap[heapSize-1].c = arbNumber;
        myHeap[heapSize-1].freq = tempLeft->freq + tempRight->freq;
        myHeap[heapSize-1].left = tempLeft;
        myHeap[heapSize-1].right = tempRight;
        arbNumber++;
    }

    //finds a character in an array
    int find(node thisArray[], char target, int size){ //looks for the character in the heap
        for(int i = 0; i < size; i++){
            //if it is found, return the index
            if((char)(thisArray[i].c) == target){
               return i;
            }
        }
        //if it was not found, return -1
        return -1;
    }

private:
    node* myHeap;
    string* encryptions;
    node* visited;
    int heapSize;
    int origHeapSize;
    unsigned int arbNumber = 133;
    int numArbs; 
};
#endif

And the rest "main" code is:

#include <iostream>
#include <fstream>
#include <string>
#include "heap.cpp"
using namespace std;
int main(int argc, char *argv[]){
string origMessage;

//creates a file stream to read from
ifstream input(argv[1]);//(argv[1]);
if (!input.is_open()) {
    cout << "Could not open file myoutfile.txt." << endl;
    return 1;
}
getline(input, origMessage);

//creates all the output streams
ofstream preOrderOutput("preorder.txt");
ofstream inOrderOutput("inorder.txt");
ofstream codeOutput("code.txt");

//cout << origMessage << endl; //testing to see if the file was read correctly

heap myHeap(origMessage, preOrderOutput, inOrderOutput, codeOutput);

return 0;
};

My test file, test.txt, holds: ALLALABAMAFOOTBALL My makefile is: all:g++ -Wall -std=c++11 heap.cpp huffmanTree.cpp -o encode

And to run it I wrote, ./encode test.txt I appreciate all help given!

Aucun commentaire:

Enregistrer un commentaire