Как правильно освободить память для данной реализации словаря в С
Необходимо реализовать словарь в Си, в котором ключ и значение являются строками.
Нашел в книжке простой вариант реализации словаря. Но не совсем получается полностью освобождать память после его использования.
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
struct nlist { /* table entry: */
struct nlist* next; /* next entry in chain */
char* name; /* defined name */
char* defn; /* replacement text */
};
#define HASHSIZE 1
static struct nlist* hashtab[HASHSIZE]; /* pointer table */
/* hash: form hash value for string s */
unsigned hash(char* s) {
unsigned hashval;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31 * hashval;
return hashval % HASHSIZE;
}
struct nlist* lookup(char* s) {
struct nlist* np;
for (np = hashtab[hash(s)]; np != NULL; np = np->next)
if (strcmp(s, np->name) == 0)
return np; /* found */
return NULL; /* not found */
}
struct nlist* install(char* name, char* defn) {
struct nlist* np;
unsigned hashval;
if ((np = lookup(name)) == NULL) { /* not found */
np = (struct nlist*)malloc(sizeof(*np));
if (np == NULL || (np->name = _strdup(name)) == NULL)
return NULL;
hashval = hash(name);
np->next = hashtab[hashval];
hashtab[hashval] = np;
}
else /* already there */
free((void*)np->defn); /*free previous defn */
if ((np->defn = _strdup(defn)) == NULL)
return NULL;
return np;
}
int __init() {
puts("INIT");
unsigned i;
for (i = 0; i < HASHSIZE; i++) {
hashtab[i] = NULL;
}
return 0;
}
void __cleanup() {
puts("CLEANUP");
unsigned i;
struct nlist* np;
struct nlist* next;
for (i = 0; i < HASHSIZE; i++) {
for (np = hashtab[i]; np != NULL; np = next) {
next = np->next;
free(np->defn);
free(np->name);
free(np);
}
hashtab[i] = NULL;
}
}
int main() {
unsigned i;
for (i = 0; i < 3; i++) {
__init();
char buf[10];
char buf2[10];
unsigned j;
for (j = 0; j < 25000; j++) {
sprintf(buf, "N%d", j);
sprintf(buf2, "V%d", j);
install(buf, buf2);
}
__cleanup();
}
getchar();
return 0;
}
Программа работает по принципу ВКЛ/ВЫКЛ. В момент запуска вызывается __init, в момент остановки __cleanup, в котором и должна производится очистка словаря. (__init и __cleanup не из книги)
В программе используется цикл, чтобы cымитиpoвaть переключение состояния программы.
Запустив код в MS Visual Studio, можно наблюдать, что при вызове __cleanup память освобождается лишь частично.
Подскажите, пожалуйста, в какую сторону копать.
