You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中使用链表解决冲突的哈希表内存分配问题求助

问题分析与修复方案

以下是代码中存在的可直接导致运行异常的错误:

  • 新创建的哈希项未接入哈希表结构:你在create_item函数中遍历完对应索引的链表尾部后,仅给新节点设置了prev指针,没有将新节点挂载到链表上。如果当前索引的链表为空(prev为NULL),需要将table->items[index]指向新节点;如果链表不为空,需要将前序节点的next指针指向新节点。否则新节点完全脱离哈希表的管理,不仅后续访问不到,还会造成内存泄漏。
  • 打印函数存在内存操作错误:print_table中你为迭代器指针额外申请了内存,随后直接将迭代器赋值为链表节点的地址,刚申请的内存直接泄漏;遍历结束后迭代器已经为NULL,此时的free操作也属于无意义的冗余代码。迭代器仅作为遍历用的指针变量,不需要单独分配内存。
  • 存在缓冲区溢出风险:当前你固定分配200字节存储key和value,若传入的字符串长度超过199会触发缓冲区溢出,建议根据实际字符串长度动态分配内存。
  • 冗余初始化逻辑:create_table中你用calloc申请的items数组已经默认初始化为全0,所有元素指针本身就是NULL,后续的循环赋值操作属于冗余代码,不影响运行但无意义。
修正后完整代码
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define CAPACITY 50000 

unsigned long hash(char *str) { 
    unsigned long int stringsum = 0; 
    for(; *str != '\0'; str++) { 
        stringsum += *str; 
    } 
    return stringsum % CAPACITY; 
} 

typedef struct item  { 
    char *value; 
    char *key; 
    struct item *next; 
    struct item *prev; 
} ht_item; 

typedef struct hashtable { 
    ht_item **items; 
    int dim; 
    int count; 
} HashTable; 

HashTable* create_table(int size);
// 函数名调整为更贴合语义的insert_item,原create_item语义不准确
void insert_item(HashTable *table, char *value, char *key); 
void print_table(HashTable* table, int dim); 

int main(void) { 
    HashTable *table = create_table(CAPACITY); 
    insert_item(table, "Giuseppe", "Nome"); 
    print_table(table, CAPACITY);
    // 实际使用时记得补充哈希表销毁逻辑,释放所有节点内存避免泄漏
    return 0; 
} 

void insert_item(HashTable *table, char *value, char *key) { 
    unsigned long index = hash(key);
    printf("当前key的哈希索引:%lu\n", index); 
    ht_item *_iterator; 
    ht_item *prev;
    for(_iterator = table->items[index], prev = NULL; _iterator != NULL; prev = _iterator, _iterator = _iterator->next);
    _iterator = (ht_item*)malloc(sizeof(ht_item));
    // 按实际字符串长度分配内存,避免溢出
    _iterator->key = (char*)malloc(strlen(key) + 1);
    _iterator->value = (char*)malloc(strlen(value) + 1); 
    strcpy(_iterator->key, key);
    strcpy(_iterator->value, value);
    _iterator->next = NULL;
    _iterator->prev = prev; 
    // 新增:把新节点挂载到链表上
    if (prev == NULL) {
        table->items[index] = _iterator;
    } else {
        prev->next = _iterator;
    }
    table->count++;
} 

HashTable* create_table(int size)
{ 
    HashTable *table = (HashTable*)malloc(sizeof(HashTable));
    table->dim = size; 
    table->count = 0;
    table->items = (ht_item**)calloc(size, sizeof(ht_item*)); 
    return table; 
} 

void print_table(HashTable* table, int dim) { 
    for(int i = 0; i < dim; i++) { 
        if(table->items[i] != NULL) { 
            // 迭代器不需要分配内存,直接指向链表头即可
            ht_item *_iterator = table->items[i];
            for(; _iterator != NULL; _iterator = _iterator->next) { 
                printf("索引:%d\tKey: %s\tValue: %s\n", i, _iterator->key, _iterator->value); 
            }
        } 
    } 
}

内容的提问来源于stack exchange,提问作者aocLEL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:15:03