-1

so I have hit a block with my code and i just cant seem to understand why I am segfaulting at the very end when i try to print out a string of encoded binary digits for a huffman tree. I have used gdb to double check my work and i just cant seem to understand why my printbin() function simply wont work, it should be encoding the traversal of the tree .. Can anyone help me ?

#include    "h_node.h"
#define     ASCII 256


/* How to check if we are at the leaflet */

int isLeaf(h_node *root) {

    return !(root->left) && !(root->right); 
} 


/* To print the codes  */
void printBin(h_node *root,char arr[], int n) {

    /* To assign 0 */
    if (root -> left){
        arr[n] = 0;
        printBin(root -> left, arr, ++n);
    }


    /* To assign 1 */
    if (root -> right){
        arr[n] = 1;
        printBin(root -> right, arr, ++n );
    }

   //  Check if we are at the leaf 
    if (isLeaf(root)){
        int i;
        printf(" \n %c: ", root -> letter);
        for (i = 0; i < n; i++)
            printf("%d", arr[i]);
        printf("\n");

    }

}

/*  Creating the treeNode */
h_node *createNode(char a, int i, h_node *l, h_node *r) {
    h_node *node = calloc(1,sizeof(h_node));
    if (node) {
        node -> letter = a;
        node -> freq = i;
        node -> next = NULL;
        node -> left = l;
        node -> right = r;       
    }
   return node;
}


/*   Function to check size of file */

off_t fsize(const char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
        return 0;
}   


/*  Sorting algorithm */
void h_sort(h_node a[], int size){
    for (int c = 0; c < (size-1); c++) {
        int pos = c;
        if ( a[c].freq != 0 ) {
            for (int d = c + 1; d < size; d++) {
                if(a[pos].freq > a[d].freq)
                    pos = d;   
            }
            if ( pos != c ) {
                h_node swap = a[c];
                a[c] = a[pos];
                a[pos] = swap;
            }   
        }
    }
}
///////////////////////////////////////////////////////////
int compare(h_node *one, h_node *two) {
   int result;
   result = (one -> freq) - (two -> freq);
   if(!result) {
      result = (one -> letter) - (two -> letter);
   }
   return result;
}
////////////
h_node *insert_ll(h_node *ll, h_node *t) {

   h_node *temp;

   if(!ll || (compare(ll, t) > 0)) {
      t -> next = ll;
      temp = t;
   } else {
      temp = ll;

      while(ll -> next && (compare(ll -> next, t) < 0)) {
         ll = ll -> next;
      }

      t -> next = ll -> next;
      ll -> next = t;
   }

   return temp;
}
////////////////////
h_node *insert_tree(h_node *list, h_node *new) {

   h_node *temp;

   if(!list || new -> freq <= list -> freq) {
      new -> next = list;
      temp = new;
   }else{
      temp = list;

      while(list -> next && list -> next -> freq < new -> freq) {
         list = list -> next;
      }

      new -> next = list -> next;
      list -> next = new;
   }

   return temp;
}


/* This will parse my sorted list and take two structures at a time  */
h_node *create_tree(h_node *list) {

   h_node *new, *head, *left, *right;
   int sum;

   head = list;

   while(head -> next != NULL) {

      left = head;
      head = head -> next;

      /*
       * If head is null, end of list has been reached
       */
      if(!head) {
         break;
      }


      right = head;
      head = head -> next;

      sum = (left -> freq) + (right -> freq);

      if (left -> freq > right -> freq)
        new = createNode(left -> letter, sum, left, right);
      if (left -> freq == right -> freq)
        new = createNode(left -> letter,sum,left,right);
      if (left -> freq < right -> freq)
        new = createNode(right -> letter,sum,left,right);

      head = insert_tree(head, new); 
   }

   return head;
}

void treeprint(struct h_node *p){
    if ( p != NULL ){
        treeprint(p->left);
        printf("\n %d %x \n",p->freq, p->letter);
        treeprint(p->right);
    }
}



/*  Sorting algorithm */
void sort(int a[], int size){
    for (int c = 0; c < (size-1); c++) {
        int pos = c;
        if ( a[c] != 0 ) {
            for (int d = c + 1; d < size; d++) {
                if(a[pos] > a[d])
                    pos = d;   
            }
            if ( pos != c ) {
                int swap = a[c];
                a[c] = a[pos];
                a[pos] = swap;
            }   
        }
    }
}

/*  Finding the frequency */
void freq(char a[],int d[]) {

    int c = 0;

    while (a[c] != '\0'){ 
        d[(int)a[c]]++;
        c++;
    }

}



/* Start of Main  */

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




    char ch;
    FILE *fp;    
    int i=0;
    int j = 0;
    int sameness = 0;
    int size = fsize(argv[1]);
     h_node *head = NULL;
      //h_node *new;


    printf("The size is %d\n",size);

    fp = fopen(argv[1], "r"); // read mode

    if (fp == NULL)
    { 
       perror("Error while opening the file.\n");
       exit(EXIT_FAILURE);
    }

    /* Now we create that array of size .. size */
    char *arr =calloc(fsize(argv[1]),sizeof(char));  
    int *count =calloc(ASCII,sizeof(int));

    printf("The size of the file is %ld\n",fsize(argv[1])); 

    /* This will copy each charater from the file into an array  */
    while((ch = fgetc(fp)) != EOF){
          arr[i++] = ch;
          fflush(fp);
    }     

    /* This is just to check to make sure everything properly prints out */
    printf("The contents of the file are:\n"); 
    for (int i = 0; i <= size-1; i++)
        printf("%c ", arr[i]);

    /* Now we want to selection sort the array so that it is in ascii value  */
    printf("\nThis is i : %d\n", i); 

    /* Now we want to count frequency */
    freq(arr,count);

    /* Now we want to sort by Frequency */
    //sort(count,256); 
    printf("\n");
    for (i = 0; i < ASCII; i++){
        if(count[i] != 0){
            sameness +=1;
            printf("%c %d\n ",i,count[i]);  
        }
    }

    printf("\n this is the sizeof sameness : %d \n", sameness);

    struct h_node* h_arr=calloc(sameness,sizeof(h_node));

    /* This is just to check to make sure everything properly prints out */
    printf("The contents of the file are:\n"); 
    for (int i = 0; i < ASCII; i++)
        if(count[i] != 0){
                printf("0x%x happens: %d time(s)\n", i,count[i]);
                h_arr[j].letter = i;
                printf("0x%x \n",h_arr[j].letter);
                h_arr[j].freq = count[i];
                printf("  %d \n",h_arr[j].freq);
                j++;
        }




     struct h_node* h_arr2=calloc(sameness,sizeof(h_node));


    for (int i = 0; i < sameness; i++){
        for (int p = i + 1 ; p < sameness; p++)
            if(h_arr[i].freq > h_arr[i + 1].freq){
                if( i == 0)
                    h_arr2[i] = *createNode(h_arr[i].letter, 
                        h_arr[i].freq,NULL,NULL);
                h_arr2[i]= *createNode(h_arr[i].letter,
                    h_arr[i].freq,&h_arr[i],&h_arr[i+1]);
            }    
            else
               if ( i == 0 )
                   h_arr2[i] = *createNode(h_arr[i + 1].letter, 
                        h_arr[i + 1].freq,NULL,NULL);
                h_arr2[i] = *createNode(h_arr[i].letter, 
                    h_arr[i].freq,&h_arr[i],&h_arr[i]);
        }

     h_sort(h_arr2,sameness); 
    for (int i = 0; i < sameness; i++)
        printf("\n hi %x %d %x %d\n", h_arr2[i].letter, 
            h_arr2[i].freq,h_arr2[i].left -> letter,h_arr2[i].right -> freq); 



    //This will be to input the nodes into a LL //
    for (int i = 0; i < sameness; i++){
       head = insert_ll(&h_arr2[i], &h_arr2[i+1]);
    }

   head = create_tree(head);
   char *codes =(char *) malloc(sizeof(char)); 

   printBin(head,codes,0);


    /* Test to make sure it prints out correctly */
    printf("\n\n");
    printf("this is i: %d\n",i);
    printf("%d\n",size);

    free(arr);
    free(count);

    fclose(fp);
    return 0;
}
Mihai G
  • 27
  • 2
  • 5
  • 2
    ya know there is a shift key usually two on your keyboard if you look close youll also find interpunction marks which would make your text a lot easier to read for the people you want help from consider this and maybe edit your question also a [\*\*\*minimal\*\*\* complete verifiable example](https://stackoverflow.com/help/mcve) could help – Swordfish Oct 19 '18 at 02:54

1 Answers1

1

You call printBin with 'codes' pointing to a single character. If it recurses more than one level, you're pointing at unallocated memory. At that point, you'll end up overwriting something important. That's probably the source of your seg fault.

Dervish
  • 66
  • 4