2012-02-24 3 views
1

다음과 같이 해시 테이블 구조를 구현했습니다 (텍스트 파일에서 모든 단어를 읽고 해시 테이블을 구성한 다음 한 줄에 모든 값을 인쇄합니다) :C 해시 테이블 구현의 메모리 누수

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

unsigned int hashf(const char *buf, size_t len) { 
    unsigned int h = 0; 
    size_t i; 
    for (i = 0; i < len; i++) { 
     h += buf[i]; 
     h += h << 10; 
     h ^= h >> 7; 
    } 
    h += h << 3; 
    h ^= h >> 11; 
    h += h << 15; 
    return h; 
} 

void destroy_hash(char *hashtable[], int table_size) { 
    int i; 
    for (i=0; i<table_size; i++) { 
     if (hashtable[i]) { 
      free(hashtable[i]); 
     } 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    if (argc != 3) { 
     printf("Invalid parameters!\n"); 
     return EXIT_FAILURE; 
    } 
    const char *filename = argv[1]; 
    int table_size = atoi(argv[2]); 

    char *hashtable[table_size]; 
    int i; 
    for (i = 0; i < table_size; i++) { 
     hashtable[i] = NULL; 
    } 
    unsigned int h, h_k; 

    FILE *fileread = fopen(filename, "r"); 

    char *key; 
    char buf[100]; 
    int probe_nro, word_nro = 0; 

    if (fileread) { 

     fscanf(fileread, "%99s", buf); 
     key = malloc((strlen(buf)+1)*sizeof(char)); 
     memcpy(key, buf, strlen(buf) + 1); 
     while(!feof(fileread)) { 
      // Increase word_nro by 1 
      word_nro += 1; 
      if (word_nro <= table_size) { 
       h = hashf(key, strlen(buf)) % table_size; 
       if (!hashtable[h]) { 
        hashtable[h] = key; 
       } 
       else { 
        // Begin probing 
        probe_nro = 1; 
        // Save original hash to h_k: 
        h_k = h; 

        h = (h_k+(probe_nro*probe_nro)) % table_size; 

        while (hashtable[h] && (probe_nro <= 10000)) { 
         probe_nro += 1; 
         h = (h_k+(probe_nro*probe_nro)) % table_size; 
        } 
        // If no vacancy found after 10000 probes, return error 
        if (probe_nro == 10000) { 
         printf("Error: table full\n"); 
         free(key); 
         destroy_hash(hashtable, table_size); 
         return(1); 
        } 
        hashtable[h] = key; 
       } 
       fscanf(fileread, "%99s", buf); 
       if (!feof(fileread)) { 
        key = malloc((strlen(buf)+1)*sizeof(char)); 
        memcpy(key, buf, strlen(buf) + 1); 
       } 
      } 
     else { 
      free(key); 
      printf("Error: table full\n"); 
      destroy_hash(hashtable, table_size); 
      return(1); 
     } 
    } 
    for (i=0; i < table_size; i++) { 
     if (hashtable[i]) { 
      printf("%s", hashtable[i]); 
     } 
     else { 
      printf(" "); 
     } 
     if (i < table_size - 1) { 
      printf(","); 
     } 
    } 
    printf("\n"); 
    destroy_hash(hashtable, table_size); 
} 
else { 
    printf("Can't open file!\n"); 
    return(1); 
} 
return(0); 
} 
내가 같이 Valgrind의에 표시되어있는 메모리 누수, 찾을 수없는

: 총 힙 사용 : 당신이 할 수있는 1 개 블록

에서 568 바이트 : 7 allocs, 6 개 해방는 604 바이트는 여전히 도달 을 할당 어쩌면 내가 알아야 할 것, 내가 아직도 자유해야 할 것, 또는 내가 잘못하고있는 것? 많은 감사합니다. 당신은 당신이 malloc에 할당 된 메모리를 해제하지 않고 새 위치로 key 점하고 있습니다이 줄

if (!feof(fileread)) { 
    key = malloc((strlen(buf)+1)*sizeof(char)); 
    memcpy(key, buf, strlen(buf) + 1); // <-- 
} 

답변

1

. 그것은 최초의 malloc이 수행되기 전에 확보하기 때문에이 실패합니다

if (!feof(fileread)) { 
    free(key); // <-- 
    key = malloc((strlen(buf)+1)*sizeof(char)); 
    memcpy(key, buf, strlen(buf) + 1); 
} 
+0

해야한다. 대신, 키를 NULL로 초기화하도록 선언을 변경하고 free() 호출을 조건부로 만듭니다. – mah

+0

@Seth Carnegie : 내가 추가 할 때, "해제 된 포인터가 할당되지 않았습니다."라는 메시지가 나타납니다. – rize

+0

@mah : 좀 더 정확해질 수 있습니까? – rize

-1
void destroy_hash(char *hashtable[], int table_size) { 
    int i; 
    for (i=0; i<table_size; i++) { 
     if (hashtable[i]) { 
      free(hashtable[i]); 
      hashtable[i] = NULL; /* this one ? */ 
     } 
    } 
}