c - Program Segmentation Faults on return 0/fclose/free. I think I have memory leaks but can't find them. Please help! -
i trying write huffman encoding program compress text file. upon completetion, program terminate @ return statement, or when attempt close file reading from. assume have memory leaks, cannot find them. if can spot them, let me know (and method fixing them appreciated!).
(note: small1.txt standard text file)
here main program
#include<stdio.h> #include<string.h> #include<stdlib.h> #define ascii 255 struct link { int freq; char ch[ascii]; struct link* right; struct link* left; }; typedef struct link node; typedef char * string; file * ofp; file * ifp; int writebit(unsigned char); void sort(node *[], int); node* create(char[], int); void sright(node *[], int); void assign_code(node*, int[], int, string *); void delete_tree(node *); int main(int argc, char *argv[]) { //hard-coded variables //counters int a, b, c = 0; //arrays char *key = (char*) malloc(ascii * sizeof(char*)); int *value = (int*) malloc(ascii * sizeof(int*)); //file pointers file *fp = fopen(argv[1], "r"); if (fp == null) { fprintf(stderr, "can't open %s\n", argv[1]); return 0; } //nodes node* ptr;//, *head; node* array[ascii]; // int u, carray[ascii]; char str[ascii]; //variables char car = 0; int inlist = 0; int placeinlist = -1; int numofkeys; if (argc < 2) { printf("usage: huff <.txt file> \n"); return 0; } (a = 0; < ascii; a++) { key[a] = -1; value[a] = 0; } car = fgetc(fp); while (!feof(fp)) { (a = 0; < ascii; a++) { if (key[a] == car) { inlist = 1; placeinlist = a; } } if (inlist) { //increment value array value[placeinlist]++; inlist = 0; } else { (b = 0; b < ascii; b++) { if (key[b] == -1) { key[b] = car; break; } } } car = fgetc(fp); } fclose(fp); c = 0; (a = 0; < ascii; a++) { if (key[a] != -1) { array[c] = create(&key[a], value[a]); numofkeys = c; c++; } } string code_string[numofkeys]; while (numofkeys > 1) { sort(array, numofkeys); u = array[0]->freq + array[1]->freq; strcpy(str, array[0]->ch); strcat(str, array[1]->ch); ptr = create(str, u); ptr->right = array[1]; ptr->left = array[0]; array[0] = ptr; sright(array, numofkeys); numofkeys--; } assign_code(array[0], carray, 0, code_string); ofp = fopen("small1.txt.huff", "w"); ifp = fopen("small1.txt", "r"); car = fgetc(ifp); while (!feof(ifp)) { (a = 0; < ascii; a++) { if (key[a] == car) { (b = 0; b < strlen(code_string[a]); b++) { if (code_string[a][b] == 48) { writebit(0); } else if (code_string[a][b] == 49) { writebit(1); } } } } car = fgetc(ifp); } writebit(255); fclose(ofp); ifp = fopen("small1.txt", "r"); fclose(ifp); free(key); //free(value); //free(code_string); printf("here1\n"); return 0; } int writebit(unsigned char bitval) { static unsigned char bitstogo = 8; static unsigned char x = 0; if ((bitval == 0) || (bitval == 1)) { if (bitstogo == 0) { fputc(x, ofp); x = 0; bitstogo = 8; } x = (x << 1) | bitval; bitstogo--; } else { x = (x << bitstogo); fputc(x, ofp); } return 0; } void assign_code(node* tree, int c[], int n, string * s) { int i; static int cnt = 0; string buf = malloc(ascii); if ((tree->left == null) && (tree->right == null)) { (i = 0; < n; i++) { sprintf(buf, "%s%d", buf, c[i]); } s[cnt] = buf; cnt++; } else { c[n] = 1; n++; assign_code(tree->left, c, n, s); c[n - 1] = 0; assign_code(tree->right, c, n, s); } } node* create(char a[], int x) { node* ptr; ptr = (node *) malloc(sizeof(node)); ptr->freq = x; strcpy(ptr->ch, a); ptr->right = ptr->left = null; return (ptr); } void sort(node* a[], int n) { int i, j; node* temp; (i = 0; < n - 1; i++) (j = i; j < n; j++) if (a[i]->freq > a[j]->freq) { temp = a[i]; a[i] = a[j]; a[j] = temp; } } void sright(node* a[], int n) { int i; (i = 1; < n - 1; i++) a[i] = a[i + 1]; }
if program crashing on otherwise valid operation (like returning function or closing file), i'll near-guarantee it's buffer overflow problem rather memory leak.
memory leaks mean mallocs fail, not mean other operations affected. buffer overflow of item on stack (for example) corrupt other items on stack near (such file handle variable or return address main
).
probably best bet set conditional breakpoint on writes file handles. should happen in calls fopen
, else. if detect write after fopen
calls finished, problem occurred, examine stack , executing line find out why.
your first problem (this not one) lies here:
c = 0; (a = 0; < ascii; a++) { if (key[a] != -1) { array[c] = create(&key[a], value[a]); numofkeys = c; // danger, c++; // robinson !! } } string code_string[numofkeys];
you can see set number of keys before increment c
. means number of keys 1 less need that, when access last element of code_string
, you're accessing something else (which unlikely valid pointer).
swap numofkeys = c;
, c++;
around. when that, @ least bit printing here1
, exit without core dump. can't vouch correctness of rest of code solves segmentation violation else should go in next question (if need be).
Comments
Post a Comment