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

发布于 2024-07-18 11:15:20 字数 1552 浏览 7 评论 0原文

更新的问题在这里

哈希表中的内存分配问题

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

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 方面的专家,如果这有帮助的话。

Updated question is here

Memory allocation problem in HashTable

I'm working on making a HashTable in C. This is what I've done. I think I'm going on a right path but when I'm trying to

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 is a 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 *);
    };
...
...

When I run my debugger, I see no memory being allocated to myList. In above example, my attempt is to make it an array of 10 lists.

Please help me to solve this.

I'm not that expert in C, if that helps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心如狂蝶 2024-07-25 11:15:20
calloc(capacity, sizeof(ListPtr)

应该

calloc(capacity, sizeof(List)
calloc(capacity, sizeof(ListPtr)

should be

calloc(capacity, sizeof(List)

我认为这里存在很多问题。 您还没有包含您遇到的错误,所以我将列出几个:

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

I think there are a whole host of problems here. You haven't included the error you getting so, I will list a couple:

  • hash = (HashTablePtr) malloc(sizeof(HashTablePtr*)); - You are allocating the size of a HashTable **, which is four bytes, you need to allocate the size of the underlying object.
  • ListPtr mylist = (ListPtr* )calloc(capacity, sizeof(ListPtr)); - Again, your are allocating the size of the pointer rather than the underlying list object.
  • HashTablePtr createHashTable(unsigned int capacity)){ - You are probably getting a compile error here with the extra parens and the inconsistent number of parameters.
缺⑴份安定 2024-07-25 11:15:20

就我个人而言,我不太喜欢使用 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);

Personally I am not a huge fan of using typedefs, especially when you are a beginner. I think that may be partially what is confusing you. You are better avoiding things like:

typedef struct hashtable * HashTablePtr;

Using to many typedefs will make your code harder to read since you will need to constantly look up what they are referring too.

The main problem is that you were allocating the memory for the size of a hashtable/list pointer and not for the size of their respected structures. I think the code below shows this well. You will also want to check if you allocations worked. If malloc, calloc, realloc. etc. fail they return NULL. If this happens and you do not check for this case you will get a segfault error and your program will crash.

Also follow the c99 standard, and put all of your variable declarations at the start of the function.

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

Also remember to free you list before you free your hashtable:

free(myhash->list);
free(myhash);
少女情怀诗 2024-07-25 11:15:20

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

calloc(capacity, sizeof(List));

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

You are allocating a contigous block of ListPtr's, but you actually want to allocate space for the all the structures rather than just pointers (ListPtr) to those structures:

calloc(capacity, sizeof(List));

I agree with gman's comment about not hiding pointers. When coding in C, I never typdef a List * as a ListPtr. It makes the code harder to understand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文