0

更新的问题在这里

HashTable中的内存分配问题

我正在用 C 制作一个 HashTable。这就是我所做的。我想我正走在正确的道路上,但是当我试图

主程序

HashTablePtr hash;
hash = createHashTable(10);
insert(hash, "hello");
insert(hash, "world");

哈希表.c

    HashTablePtr createHashTable(unsigned int capacity){
    HashTablePtr hash;
    hash = (HashTablePtr) malloc(sizeof(HashTablePtr));
    hash->size = 0;
    hash->capacity = capacity;
    ListPtr mylist = (ListPtr)calloc(capacity, sizeof(ListPtr)); /* WHY IT DOESN'T ALLOCATE MEMORY FOR mylist HERE?? */
    mylist->head = NULL;
    mylist->size = 0;
    mylist->tail = NULL;    
    hash->list = mylist;  
    return hash;

ListPtr 是一个 LinkedList ptr

列表.h

typedef struct list List;
typedef struct list * ListPtr;

struct list {
    int size;
    NodePtr head;
    NodePtr tail;
};
...
...

哈希表.h

    typedef struct hashtable * HashTablePtr;
    typedef struct hashtable HashTable;
    struct hashtable {
        unsigned int capacity;
        unsigned int size;
        ListPtr *list;
        unsigned int (*makeHash)(unsigned int, void *);
    };
...
...

当我运行调试器时,我看到没有分配给 myList 的内存。在上面的示例中,我的尝试是使其成为 10 个列表的数组。

请帮我解决这个问题。

如果有帮助的话,我不是 C 方面的专家。

4

4 回答 4

2

就我个人而言,我不是使用 typedef 的超级粉丝,尤其是当您是初学者时。我认为这可能是让你感到困惑的部分原因。你最好避免这样的事情:

typedef struct hashtable * HashTablePtr;

使用过多的 typedef 将使您的代码更难阅读,因为您也需要不断地查找它们所指的内容。

主要问题是您为哈希表/列表指针的大小分配内存,而不是为它们所尊重的结构的大小分配内存。我认为下面的代码很好地说明了这一点。您还需要检查您的分配是否有效。如果是 malloc、calloc、realloc。等失败他们返回NULL。如果发生这种情况并且您没有检查这种情况,您将收到一个段错误并且您的程序将崩溃。

还要遵循 c99 标准,并将所有变量声明放在函数的开头。

c99标准

malloc 手册页

struct hashtable *
createHashTable(unsigned int capacity){
    struct hashtable *hash;
    struct list *mylist;

    /* You want to allocate size of the hash structure not the size of a pointer. */
    hash = malloc(sizeof(struct hashtable)); 
    // always make sure if the allocation worked.
    if(hash == NULL){
        fprintf(stderr, "Could not allocate hashtable\n");
        return NULL;
    }

    hash->size = 0;
    hash->capacity = capacity;

    /* Unless you need the memory to be zero'd I would just use malloc here
     * mylist = calloc(capacity, sizeof(struct list)); */
    mylist = malloc(capacity * sizeof(struct list));
    if(mylist == NULL){
        fprintf(stderr, "Could not allocate list\n");
        free(hash); /* free our memory and handle the error*/
        return NULL;
    }

    mylist->head = NULL;
    mylist->size = 0;
    mylist->tail = NULL;    
    hash->list = mylist;

    return hash;
}

还记得在释放哈希表之前释放你的列表:

free(myhash->list);
free(myhash);
于 2009-05-06T12:18:29.063 回答
2
calloc(capacity, sizeof(ListPtr)

应该

calloc(capacity, sizeof(List)
于 2009-05-06T04:21:07.477 回答
2

我认为这里有很多问题。你没有包括你得到的错误,我将列出几个:

  • 哈希 = (HashTablePtr) malloc(sizeof(HashTablePtr*)); - 你正在分配一个HashTable **的大小,也就是四个字节,你需要分配底层对象的大小。
  • ListPtr mylist = (ListPtr* )calloc(容量, sizeof(ListPtr)); - 同样,您正在分配指针的大小而不是基础列表对象。
  • HashTablePtr createHashTable(unsigned int capacity)){ - 你可能会因为额外的括号和参数数量不一致而出现编译错误。
于 2009-05-06T04:23:01.157 回答
0

您正在分配一个连续的 ListPtr 块,但您实际上想要为所有结构分配空间,而不仅仅是指向这些结构的指针 (ListPtr):

calloc(capacity, sizeof(List));

我同意 gman 关于不隐藏指针的评论。在 C 中编码时,我从不将 a 输入List *ListPtr. 它使代码更难理解。

于 2009-05-06T04:20:22.300 回答