我对结构使用uthash哈希表实现。
我有两个哈希表,其中一个(代码中的 dataTable )在循环中收集一些信息,当它完成时,将一些数据保存在另一个哈希表中(即 stuffTable )。我的程序工作(至少有小文件)但是当我用valgrind检查时,它会发现第二个哈希表的内存泄漏( stuffTable )(但第一个表没有泄漏,尽管我释放了它以同样的方式)
==12075== Invalid read of size 8
==12075== at 0x111CEE: deleteTable (myTest.c:1456)
==12075== by 0x116AE6: getResults (myTest.c:1980)
==12075== by 0x117E69: packetLoop (myTest.c:2350)
==12075== by 0x1114C1: main (myTest.c:2872)
==12075== Address 0x8335498 is 40 bytes inside a block of size 96 free'd
==12075== at 0x4C2D16B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12075== by 0x111CE0: deleteTable (myTest.c:1458)
==12075== by 0x116AE6: getResults (myTest.c:1980)
==12075== by 0x117E69: packetLoop (myTest.c:2350)
==12075== by 0x1114C1: main (myTest.c:2872)
==12075== Block was alloc'd at
==12075== at 0x4C2DF55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12075== by 0x112046: getStuffs (myTest.c:1475)
==12075== by 0x116A75: getResults (myTest.c:1972)
==12075== by 0x117E69: packetLoop (myTest.c:2350)
==12075== by 0x1114C1: main (myTest.c:2872)
正如您所看到的,我只使用malloc来创建一个新节点,并且在我为其分配内存的stuff结构中没有其他数据结构。所以我不明白是什么导致内存泄漏。要删除哈希表,我使用标准程序,由uthash文档给出:
void delete_all() {
struct my_struct *current_user, *tmp;
HASH_ITER(hh, users, current_user, tmp) {
HASH_DEL(users,current_user); /* delete; users advances to next */
free(current_user); /* optional- if you want to free */
}
}
这是我的代码:
struct stuff {
u_int32_t key;
u_int32_t packets
u_int32_t bytes;
u_int32_t host;
char name[16];
UT_hash_handle hh;
};
struct stuff *myStuffTable = NULL;
struct key_data {
u_int32_t key;
u_int32_t packets;
u_int32_t bytes;
u_int32_t count;
struct triple top_host[A_SIZE];
UT_hash_handle hh;
};
struct key_data *dataTable = NULL;
struct triple {
u_int32_t host;
u_int32_t count;
char proto[16];
};
static void deleteTable(struct stuff *dataTable) {
struct stuff *current_key, *tmp;
HASH_ITER(hh, dataTable, current_key, tmp) { //(myTest.c:1456)
HASH_DEL(dataTable, current_key);
free(current_key); //(myTest.c:1458)
}
}
static void getStuffs(struct stuff **stuffTable, struct key_data *dataTable) {
struct stuff *s;
struct key_data *kd, *tmp;
struct triple inf;
HASH_ITER(hh, dataTable, kd, tmp) {
s = (struct stuff *)malloc(sizeof(struct stuff)); //(myTest.c:1475)
memset(s, 0, sizeof(struct stuff));
s->key = kd->key;
s->packets = kd->packets;
s->bytes = kd->bytes;
/* sort host array and take the first element */
qsort(&kd->hosts[0], A_SIZE, sizeof(struct triple), triple_cmp);
inf = kd->hosts[0];
if(((inf.count > THRESHOLD) {
s->host = inf.host;
strncpy(s->name, inf.name, sizeof(s->name));
}
else
s->host = 0;
HASH_ADD_INT(*stuffTable, key, s);
}
}
int main(){
.....
getStuffs(&myStuffTable, dataTable);
deleteTable(myStuffTable);
}