【问题标题】:Why does this malloc not work in C?为什么这个 malloc 在 C 中不起作用?
【发布时间】:2010-10-26 11:18:43
【问题描述】:

只是尝试制作一种哈希表,每个节点都是一个链表。

刚初始化空间时遇到问题,我做错了什么?

#include <stdlib.h>

typedef struct entry {
 struct entry *next;
 void *theData;
} Entry;


typedef struct HashTable {
 Entry **table;
 int size;
} HashTable;

int main(){
 HashTable *ml;
 ml = initialize();
 return 0;
}

HashTable *initialize(void)
{
 HashTable *p;
 Entry **b;
 int i;


 if ((p = (HashTable *)malloc(sizeof(HashTable *))) == NULL)
  return NULL;
 p->size = 101;

 if ((b = (Entry **)malloc(p->size * sizeof(Entry **))) == NULL)
         return NULL;

 p->table = b;

 for(i = 0; i < p->size; i++) {
  Entry * b =  p->table[i];
  b->theData = NULL;
  b->next = NULL;
     }

 return p;
}

【问题讨论】:

  • 作为一般要点;不要在 C 中转换 malloc() 的返回值。
  • 具体不要写p = (HashTable *)malloc(sizeof(HashTable *)),而是p = malloc(sizeof(*p))。强制转换仅用于确保 p 具有“正确的类型”,即与您用于大小的类型相同。在这种情况下,转换应该是比sizeof 中使用的类型多一个星号的类型。既然你在这里弄错了,演员表对你没有任何好处,并且可能会掩盖由于忘记包含 stdlib.h 而导致的错误消息。

标签: c pointers malloc


【解决方案1】:

您需要将 sizeof(HashTable*) 更改为 sizeof(HashTable) 并类似地将 sizeof(Entry **) 更改为 sizeof(Entry *) 。第二件事是对于每个Entry,您需要在循环内再次使用malloc 分配内存。

【讨论】:

  • 谢谢!嗯,对 sizeof(HashTable) 的 p 进行此更改会导致向 p 分配内存时出错。使用 VS 2010。会再试一次,但这似乎是它的意思。
  • 我更喜欢sizeof(*p) 而不是sizeof(HashTable)。然后该行显示“为p分配正确的东西”,而不是“分配这个东西,我认为这对p是正确的,但谁知道呢,我可能犯了一个错误”:-)跨度>
【解决方案2】:
 if ((p = malloc(sizeof(HashTable))) == NULL) 
  return NULL; 
 p->size = 101;  

 if ((b = malloc(p->size * sizeof(Entry *))) == NULL) 
         return NULL; 

我认为删除 malloc() 结果转换是最佳做法。

另外,正如@Naveen 首先指出的那样,您还需要为每个Entry 分配内存。

【讨论】:

  • 我会怎么做,试过了但仍然出现与内存相关的错误?
【解决方案3】:

首先你的 sizeofs 是错误的。 T * = malloc( num * sizeof(T)) 是正确的。你也可以使用 calloc。

您将 b 重用于不同的目的,因此很混乱。使用单个字符变量通常不太好。

p->b 的表已分配但未初始化,即它没有指向任何有用的东西,然后你试图取消引用它。

您需要先填充 Entry* 指针,如果要取消引用它们,它们必须指向有效的 Entry 结构。

您的进程可能会在 b>theData = NULL 行终止

【讨论】:

    【解决方案4】:

    此外,您可以在本地或在堆栈中足够高的某个区域静态声明您的 HashTable,使堆栈在使用时不会升序(在内存中),并将指向 HashTable 的指针传递给您的初始化函数避免malloc。 malloc 很慢。

    所以在 main 中,你可以这样做:

    哈希表; InitializeHashTable(&table);

    // 使用表(无需释放) // 只是不返回表

    【讨论】:

    • 稍后我将不得不调整表格的大小。这个想法是创建一个新表,然后我可以使用指向新表的指针。如果我以这种方式编码,不确定是否可以做到这一点?感谢您的意见,但我不确定是否诚实。
    猜你喜欢
    • 2018-11-05
    • 2020-07-01
    • 2012-09-08
    • 2014-01-09
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    相关资源
    最近更新 更多