为什么这段代码不在C中分配内存?

时间:2009-05-06 04:15:44

标签: c memory hashtable allocation

更新的问题在这里

Memory allocation problem in HashTable

我正在用C制作HashTable。这就是我所做的。我想我正走在正确的道路上但是当我想要

的main.c

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

HashTable.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

List.h

typedef struct list List;
typedef struct list * ListPtr;

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

HashTable.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 个答案:

答案 0 :(得分:2)

calloc(capacity, sizeof(ListPtr)

应该是

calloc(capacity, sizeof(List)

答案 1 :(得分:2)

我认为这里存在许多问题。你没有包含你得到的错误,我会列出一对:

  • hash =(HashTablePtr)malloc(sizeof(HashTablePtr *)); - 您正在分配HashTable **的大小,这是4个字节,您需要分配基础对象的大小。
  • ListPtr mylist =(ListPtr *)calloc(capacity,sizeof(ListPtr)); - 同样,您正在分配指针的大小而不是基础列表对象。
  • HashTablePtr createHashTable(unsigned int capacity)){ - 你可能在这里遇到了额外的parens和参数数量不一致的编译错误。

答案 2 :(得分:2)

就我个人而言,我并不是使用typedef的忠实粉丝,特别是当你是初学者时。我认为这可能部分令你感到困惑。你最好避免这样的事情:

typedef struct hashtable * HashTablePtr;

使用许多typedef会使你的代码更难阅读,因为你需要经常查找他们所指的内容。

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

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

c99 std

malloc manpage

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);

答案 3 :(得分:0)

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

calloc(capacity, sizeof(List));

我同意gman关于不隐藏指针的评论。当用C编码时,我绝不会将List *称为ListPtr。它使代码更难理解。