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周的FreeS,604个字节分配 仍可达也许是现货,我应该还是自由的,或者我做错了什么?非常感谢。
因为它试图进行第一的malloc之前释放这将失败。相反,将声明更改为初始化键为NULL,并使free()调用有条件。 – mah 2012-02-24 17:03:24
@Seth Carnegie:如果我补充一点,我会得到“指针被释放并没有被分配” – rize 2012-02-24 17:04:30
@mah:你能更准确一些:我应该在哪里设置键为NULL? – rize 2012-02-24 17:07:55