【问题标题】:Why this code doesn't allocate memory in C?为什么这段代码不在 C 中分配内存?
【发布时间】:2010-10-24 02:25:36
【问题描述】:

更新的问题在这里

Memory allocation problem in HashTable

我正在用 C 语言制作一个 HashTable。这就是我所做的。我认为我正走在正确的道路上,但是当我尝试这样做时

ma​​in.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 方面的专家。

【问题讨论】:

  • 您粘贴的代码在 createHashTable 中有许多不一致之处 - 一个额外的 ),调用 createHashTable 时的参数比实际需要的要多。这与您正在运行的代码相同吗?复制粘贴比重新输入要好,因为您可能会在此过程中引入(或修复)错误...
  • 我认为如果你不隐藏你的指针,你的很多问题都会变得明显。也就是去掉 ListPtr 和 NodePtr 什么的。
  • 哎呀!我只是想让它看起来更干净,然后把它搞砸了。对不起。
  • 而且您不需要在纯 C 中从 calloc() 中转换指针 - 转换是隐式完成的,这样可以为您提供更简洁的代码并隐藏更少的错误。

标签: c memory hashtable allocation


【解决方案1】:

我个人不是很喜欢使用 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);

【讨论】:

    【解决方案2】:

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

    calloc(capacity, sizeof(List));
    

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

    【讨论】:

      【解决方案3】:

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

      • hash = (HashTablePtr) malloc(sizeof(HashTablePtr*)); - 你在分配一个HashTable **的大小,也就是四个字节,你需要分配底层对象的大小。
      • ListPtr mylist = (ListPtr* )calloc(容量, sizeof(ListPtr)); - 同样,您分配的是指针的大小,而不是基础列表对象。
      • HashTablePtr createHashTable(unsigned int capacity)){ - 您可能在此处遇到编译错误,其中包含多余的括号和参数数量不一致。

      【讨论】:

      • 对不起,我想让它看起来更干净,所以搞砸了。我没有收到任何编译错误。
      【解决方案4】:
      calloc(capacity, sizeof(ListPtr)
      

      应该是

      calloc(capacity, sizeof(List)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 2012-12-03
        • 2010-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多