【发布时间】:2012-06-15 21:04:28
【问题描述】:
我写了一个哈希表,它基本上由这两种结构组成:
typedef struct dictEntry {
void *key;
void *value;
struct dictEntry *next;
} dictEntry;
typedef struct dict {
dictEntry **table;
unsigned long size;
unsigned long items;
} dict;
dict.table是一个多维数组,包含了所有存储的键/值对,又是一个链表。
如果哈希表的一半已满,我将其扩大一倍并重新散列:
dict *_dictRehash(dict *d) {
int i;
dict *_d;
dictEntry *dit;
_d = dictCreate(d->size * 2);
for (i = 0; i < d->size; i++) {
for (dit = d->table[i]; dit != NULL; dit = dit->next) {
_dictAddRaw(_d, dit);
}
}
/* FIXME memory leak because the old dict can never be freed */
free(d); // seg fault
return _d;
}
上面的函数使用旧哈希表中的指针并将其存储在新创建的哈希表中。释放旧的dict d 时会发生分段错误。
我怎样才能释放旧的哈希表结构而不必再次为键/值对分配内存?
为了完整性,编辑:
dict *dictCreate(unsigned long size) {
dict *d;
d = malloc(sizeof(dict));
d->size = size;
d->items = 0;
d->table = calloc(size, sizeof(dictEntry*));
return d;
}
void dictAdd(dict *d, void *key, void *value) {
dictEntry *entry;
entry = malloc(sizeof *entry);
entry->key = key;
entry->value = value;
entry->next = '\0';
if ((((float)d->items) / d->size) > 0.5) d = _dictRehash(d);
_dictAddRaw(d, entry);
}
void _dictAddRaw(dict *d, dictEntry *entry) {
int index = (hash(entry->key) & (d->size - 1));
if (d->table[index]) {
dictEntry *next, *prev;
for (next = d->table[index]; next != NULL; next = next->next) {
prev = next;
}
prev->next = entry;
} else {
d->table[index] = entry;
}
d->items++;
}
【问题讨论】:
-
不清楚;你的问题是“为什么我会出现段错误?”?
-
在任何地方使用 _underscores 会使你的代码 _very _hard _to _read。
-
是的,实际上,这就是为什么我会出现 seg 错误!会尽快改变。
-
那么 dictCreate 是做什么的呢?发布代码;-)
标签: c pointers hashtable resize