2016-07-22 69 views
-2

嗨,所以我創建一個程序,使用散列來存儲單詞和文本文件中出現次數。這按預期工作。我遇到的問題來自釋放分配的內存。免費()不釋放字符串從結構陣列

這裏是我的散列

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<ctype.h> 
#include"hash.h" 

/* 
struct listnode{ 
    char * word; 
    int count; 
}; 
*/ 

void hashCreate(struct listnode * hashTable[], int size){ 
    int i; 
    for(i=0;i<size;i++){ 
     hashTable[i]=(struct listnode *)malloc(sizeof(struct listnode)); 
     hashTable[i]->count=0; 
    } 
} 

int hash(char * data, int size) { 
    unsigned long hash = 5381; 
    char * p; 
    for (p = data; *p != '\0'; ++p) { 
    hash = (hash * 33) + *p; 
    } 
    return (int)(hash % size); 
} 

void hashAdd(char * data, struct listnode * hashTable[], int size){ 
    int key=hash(data, size); 
    hashTable[key]->word=strdup(data); 
    hashTable[key]->count+=1; 
} 

void hashPrint(struct listnode * hashTable[], int size){ 
    int i; 
    for(i=0;i<size;i++){ 
     if(hashTable[i]->count!=0) 
     printf("%s: %d \n",hashTable[i]->word,hashTable[i]->count); 
    } 
} 

void hashDelete(struct listnode * hashTable[],int size){ 
    int i; 
    for(i=0;i<size;i++){ 
     free(hashTable[i]->word); 
     free(hashTable[i]); 
    } 
} 

這就是使用它

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<ctype.h> 
#include"hash.h" 

/* 
int hash(char * data, int size) { 
    unsigned long hash = 5381; 
    char * p; 
    for (p = data; *p != '\0'; ++p) { 
    hash = (hash * 33) + *p; 
    } 
    return (int)(hash % size); 
} 
*/ 

#define SIZE 1500 


void removePunct(char * str); 
void fileRead(char * filename); 


struct listnode * hashTable[1500]; 

int main(int argc, char ** argv){ 
    int i; 
    if(argc<2) 
     fprintf(stderr,"Enter filename \n"); 

    hashCreate(hashTable, SIZE); 

    for(i=1; i<argc; i++){ 
     fileRead(argv[i]); 
    } 

    hashPrint(hashTable,SIZE); 
    hashDelete(hashTable, SIZE); 
    return 0; 
} 

void fileRead(char * filename){ 
    FILE * file = fopen(filename,"r"); 
    char word[80]; 
    if(!file){ 
     fprintf(stderr,"Error opening file \n"); 
     return; 
     } 
    while(fscanf(file, "%s", word)==1){ 
     removePunct(word); 
     hashAdd(word,hashTable,SIZE); 
    } 
    fclose(file); 
} 

void removePunct(char * str){ 
    int i,p=0; 
    for(i=0; i<strlen(str);i++){ 
     if(isalpha(str[i]) || str[i]==' '){ 
      str[p]=tolower(str[i]); 
      p++; 
     } 
    } 
    str[p]='\0'; 
} 

在我hashDelete函數的字符串沒有被釋放,這是造成內存泄漏。我通過釋放hashAdd函數中的字符串來測試它,並且沒有內存泄漏,但也沒有打印字符串。我無法找到不讓我釋放所有記憶的問題。任何幫助,將不勝感激。

回答

5

在這段代碼

void hashAdd(char * data, struct listnode * hashTable[], int size){ 
    int key=hash(data, size); 
    hashTable[key]->word=strdup(data); 
    hashTable[key]->count+=1; 
} 

您使用strdup得到一個新的字符串(用的strdup malloc分配)。如果您已經爲給定的key做過一次這樣的操作,則會泄漏內存。

所以你需要一個像一張支票:

if (hashTable[key]->word == NULL) hashTable[key]->word=strdup(data); 

然而,這需要您在創建表時初始化word爲NULL。

主題:通常情況下,您將需要處理相同的key值和一些額外的代碼。導致keydata值可能與已存儲的word相同或不同。你應該檢查的東西。如果它們相同,則可以增加count。如果它們不同,則必須有一種方法來存儲具有相同key值的兩個不同單詞。

它可能看起來像:

void hashAdd(char * data, struct listnode * hashTable[], int size){ 
    int key=hash(data, size); 
    if (hashTable[key]->word == NULL) { 
     // First time with this key 
     hashTable[key]->word=strdup(data); 
     hashTable[key]->count+=1; 
    } else { 
     // Key already used once 
     if (strcmp(data, hashTable[key]->word) == 0) { 
      // Same word 
      hashTable[key]->count+=1; 
     } else { 
      // Different word 
      // ... 
      // Add code for storing this word in another location 
      // ... 
     } 
    } 
} 
+0

謝謝。我知道它必須非常簡單,我沒有注意到。這固定了它。 –