Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Huffman Code - Segmentation Fault 11

Ok I have tried to make the Hauffman Code by my own and I have a problem when I'm trying to print the corresponding code to each letter with a recursive method.

(By this point I already created a BinaryTree and root is not NULL) Each node has a value and if it's a leaf it also has a letter, so I begin going down the tree node by node but it seems that in the recursive method the node just forgot who he was or I don't know, I have tried a lot of things. :S

The recursive method is createCode(Node* actual, string actualCode);

Here's the code:

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <queue>
using namespace std;

#define MAX_VALUE 256
int frequencies[MAX_VALUE] = {0};

struct Node {
    int value;
    char letter;
    struct Node *Left, *Right;
}*root=NULL, *temp, *left_temp, *right_temp;

struct CompareNode : public std::binary_function<Node*, Node*, bool> {
    bool operator()(const Node* lhs, const Node* rhs) const {
        if (lhs->value == rhs->value)
            return lhs->letter > rhs->letter;
        else
            return lhs->value > rhs->value;
    }
};

void createCode(Node* actual,string actualCode) {
    if (actual->Left == NULL && actual->Right == NULL) {
        cout << "For: " << actual->letter << " is " << actualCode << endl;
    }
    else {
        if (actual->Left) {
            createCode(actual->Left, actualCode + "0");
        }
        if (actual->Right) {
            createCode(actual->Right, actualCode + "1");
        }
    }
}

void createTree() {
    priority_queue<Node*, vector<Node*>, CompareNode> que;

    for (int x = 0; x < MAX_VALUE; x++) {
        if (frequencies[x] > 0) {
            temp = new Node;
            temp->value = frequencies[x];
            temp->letter = char(x);
            que.push(temp);
        }
    }

    while (que.size() > 1) {
        temp = new Node();
        temp->Left = que.top();
        que.pop();
        temp->Right = que.top();
        que.pop();
        temp->value = temp->Left->value + temp->Right->value;
        temp->letter = NULL;
        que.push(temp);
    }

    root = que.top();
    que.pop();
}

void fillArray(int argc, char *argv[]) {
    string line;
    const char* ptr;

    ifstream myFile(argv[argc - 1]);
    if (myFile.is_open()) {
        while (myFile.good()) {
            getline(myFile,line);

            if (line.length() != 0) {
                ptr = &line.at(0);

                while (*ptr != '\0')
                    ++frequencies[*ptr++];
            }
        }
    }
    else
        cout << "The file could not be open.";
}

int main(int argc, char *argv[]) {
    fillArray(argc, argv);

    createTree();

    createCode(root, "");
    return 0;
}

This is the example tree (I tried to post the image but because I'm new I could't):

Binary Tree Image

And here's the output:

For: a is 0
For:   is 10
Segmentation fault: 11

Please help :(

like image 562
Jordan Cortes Guzman Avatar asked Mar 04 '26 18:03

Jordan Cortes Guzman


1 Answers

You need to initialise the Left and Right pointers to NULL when creating the Nodes you push into the queue:

if (frequencies[x] > 0) {
    temp = new Node;
    temp->Left = NULL;
    temp->Right = NULL;
    temp->value = frequencies[x];
    temp->letter = char(x);
    que.push(temp);
}

Without explicit initialisation, these pointers have indeterminate values, and often not NULL, thus in createCode you are dereferencing invalid pointers.

like image 199
Daniel Fischer Avatar answered Mar 07 '26 07:03

Daniel Fischer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!