free()不从结构数组中释放字符串

Sea*_*her -2 c free hash dynamic-memory-allocation

嗨所以我正在创建一个程序,它使用哈希来存储文本文件中的单词及其出现次数.这按预期工作.我遇到的问题来自于释放分配的内存.

这是我的哈希

#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]);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是使用它的原因

#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';
}
Run Code Online (Sandbox Code Playgroud)

在我的hashDelete函数中,字符串没有被释放,导致内存泄漏.我通过释放hashAdd函数中的字符串来测试它,并且没有内存泄漏,但也没有打印字符串.我无法找到不让我释放所有记忆的问题.任何帮助,将不胜感激.

438*_*427 5

在这段代码中

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

strdup用来获得一个新的字符串(由strdup malloc'ed).如果你已经为一个给定的那样做了一次,key你会泄漏内存.

所以你需要一个像这样的支票:

if (hashTable[key]->word == NULL) hashTable[key]->word=strdup(data);
Run Code Online (Sandbox Code Playgroud)

但是,这需要word在创建表时初始化为NULL.

主题:通常,您需要key使用一些额外的代码来处理相同的值.data产生的值key可能与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
             // ...
         }
     }
}
Run Code Online (Sandbox Code Playgroud)