c - can't free memory correctly -
i'm working on pset6 of harvard's cs50 now, problem implement trie dictionary. managed make work small problem.
- when run valgrind check memory leak, tells me i've freed 1 more i've allocated, can't see problem in unload function.
- it warns me there uninitialized values, can't figure out although won't affect result.
here entire code:
/**************************************************************************** * dictionary.c * * computer science 50 * problem set 6 * * valgrind warn there uninitialized values, node struct, don't * know how initialize it, anyway, works @ last! * * implements dictionary's functionality. ***************************************************************************/ #include <stdbool.h> #include <ctype.h> #include "dictionary.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #define hashtable_size 5000 int count = 0; // gloabal counter typedef struct node { // data structure bool end_word; struct node *children[27]; } node; int charnumber(char c); // function prototype void freenode(node *currentnode); node root = {false,{null}}; /* * returns true if word in dictionary else false. */ bool check(const char *word) { node *ptr = &root; (int i=0;i<strlen(word);i++) { if (ptr->children[charnumber(word[i])] == null) return false; ptr = ptr->children[charnumber(word[i])]; } if (ptr->end_word) return true; else return false; } /* * loads dictionary memory. returns true if successful else false. */ bool load(const char *dictionary) { // char word[length+1]; // must initialize zero! or there weird problem. file *fp = fopen(dictionary,"r"); if (fp == null) return false; while (!feof(fp)) { char word[length+1] = {}; fscanf(fp,"%s\n",word); // have use "%s\n" instead of "%s", or count wrong, don't know why. count++; node *ptr = &root; (int i=0;i<strlen(word);i++) { if (ptr->children[charnumber(word[i])] == null) { node *new = malloc(sizeof(node)); *new = (node) {false,{null}}; // initiallization ptr->children[charnumber(word[i])] = new; ptr = new; } else { ptr = ptr->children[charnumber(word[i])]; } } ptr->end_word = true; } fclose(fp); return true; } /* * caculate number character */ int charnumber(char c) { int num; if (c == '\'') return 26; else if(c >= 'a' && c <= 'z') c += 32; num = c - 'a'; return num; } /* * returns number of words in dictionary if loaded else 0 if not yet loaded. */ unsigned int size(void) { if (count) return count; else return 0; } /* * unloads dictionary memory. returns true if successful else false. */ bool unload(void) { freenode(&root); return true; // can't figure out when return false... } void freenode(node *currentnode) { (int i=0;i<27;i++) { if (currentnode->children[i] != null) freenode(currentnode->children[i]); } free(currentnode); }
here of valgrind output:
==22110== invalid free() / delete / delete[] ==22110== @ 0x4024ecd: free (vg_replace_malloc.c:366) ==22110== 0x8048f90: freenode (dictionary_tries.c:152) ==22110== 0x8048f45: unload (dictionary_tries.c:141) ==22110== 0x8048ab5: main (speller.c:158) ==22110== address 0x804a5a0 0 bytes inside data symbol "root" ==22110== --22110-- redir: 0x40b2930 (strchrnul) redirected 0x4028570 (strchrnul) ==22110== ==22110== heap summary: ==22110== in use @ exit: 0 bytes in 0 blocks ==22110== total heap usage: 367,083 allocs, 367,084 frees, 41,113,776 bytes allocated ==22110== ==22110== heap blocks freed -- no leaks possible ==22110== ==22110== error summary: 1 errors 1 contexts (suppressed: 14 9) ==22110== ==22110== 1 errors in context 1 of 1: ==22110== invalid free() / delete / delete[] ==22110== @ 0x4024ecd: free (vg_replace_malloc.c:366) ==22110== 0x8048f90: freenode (dictionary_tries.c:152) ==22110== 0x8048f45: unload (dictionary_tries.c:141) ==22110== 0x8048ab5: main (speller.c:158) ==22110== address 0x804a5a0 0 bytes inside data symbol "root" ==22110== --22110-- --22110-- used_suppression: 14 u1004-arm-_dl_relocate_object ==22110== ==22110== error summary: 1 errors 1 contexts (suppressed: 14 9)
suppose load
function opens blank file. feof(fp)
return 0
, because read operation hasn't been used yet; eof
flag set after read operation returns value indicating error. error lies. in case, need loop on return value of fscanf(fp,"%s\n",word);
rather return value of feof
. example:
while (fscanf(fp, "%s", word) == 1) { /* ... */ } if (feof(fp)) { /* loop ended due eof */ } else if (ferror(fp)) { /* loop ended due file input error */ } else { /* loop ended because input invalid * (this applies input conversion * required eg. conversion in %d, %u, %f, etc... */ }
to elaborate, feof
only determining why last read failed!
the reason cause such warning in case of blank file word
contain indeterminate information.
additionally, freenode(&root);
erroneous because free
called on pointers returned calloc
, realloc
, malloc
.
Comments
Post a Comment