0

我想在 c 中“构造”(阅读:malloc 和 memset)我的哈希表。为此,我创建了一个函数,如下所示:

int maketable(struct hash_entry **table, int size){

    table = (struct hash_entry **)malloc(size*sizeof(struct hash_entry *));
    int i = 0;
    for (; i<size; i++) {
        memset(table[i], '\0', sizeof(struct hash_entry *));
    }
    return 0;

}

鉴于该表将被声明为

struct hash_entry **table[size]

在输入此代码之前,当我从 maketable 返回时,我不会丢失任何东西,对吧?

编辑:是否传递tablemaketable()确保只要我更改table指向的数据,更改就会被保留?

编辑二:我正在尝试分配一个指针数组,指向指向 hash_entries 的指针

4

3 回答 3

4

您的代码正在分配给局部table变量,调用者不受影响。这会导致内存泄漏。

在函数之外,您已将 table 声明为指向 struct hash_entry 指针的指针数组 - 我猜您只是想要一个指向 struct hash_entry 的指针数组。

如果您实际上声明table为数组,则无需 malloc 该空间。您只需要一个循环将其中的每个元素都设置为 NULL(不要将每个元素都设置为零)。

如果目标是分配整个表,这就是您要查找的内容:

struct hash_entry **table;
...
int maketable(struct hash_entry ***table, int size){

    *table = malloc(size* sizeof **table);
    int i = 0;
    for (; i<size; i++) {
       (*table)[i] = NULL;
    }
    return 0;
}

称之为

maketable(&table,100);

我宁愿像这样返回表格:

struct hash_entry ** maketable(int size){
   return calloc(size, sizeof(struct hash_entry *));
}

如果声明struct hash_entry **table[size]确实是您想要的,您需要告诉我们您的 maketable() 函数实际上应该做什么(例如,您是否希望将动态分配的“数组”作为该表中的元素之一?

于 2010-01-26T23:13:14.287 回答
2

您将需要将结果分配malloc* table- 否则它将在函数之外不可见。

此外,使用它的典型方法是声明一个指向哈希表的指针并将该指针的地址传递给函数。

于 2010-01-26T23:05:40.567 回答
1

不,您的类型不匹配。

您是否尝试分配哈希条目表(即table[i]is的类型struct hash_entry)、指向hash_entries的指针table[i]表(即is的类型struct hash_entry *)或其他?根据您的代码读取方式,我假设第一种情况,但如果有错误请告诉我。

假设您正在动态分配 的表struct hash_entry,则您在调用者中的表声明应该是

struct hash_entry *table; // 1 *, no array dimension

该函数应称为

int result = maketable(&table, number_of_elements);

定义

int maketable (struct hash_entry **table, size_t size)
{
  int r = 0;

  // sizeof **table == sizeof (struct hash_entry)
  *table = malloc(sizeof **table * size);
  // *ALWAYS* check the result of malloc()
  if (*table)
  {
    size_t i;
    for (i = 0; i < size; i++)
      memset(&(*table)[i], 0, sizeof (*table)[i]);
    r = 1;
  }
  return r;
}

有几点需要指出。首先,不要投射malloc(). 从 C89 开始,您不需要这样做,如果您忘记包含 stdlib.h 或malloc()在范围内没有原型,则演员表将取消诊断。其次,您可以sizeof在对象而不是类型上使用运算符。这有助于减少一些维护难题(即,如果您更改table参数列表中的类型,则不必随之更改sizeof调用)。

最后,注意表的地址被传递给函数;因为我们试图写入一个指针值,所以我们必须传递一个指向该指针的指针。

如果您尝试创建指向 的指针表struct hash_entry,则代码基本相同,只是多了一层间接性:

您在调用者中的表声明应该是

struct hash_entry **table; // 2 *, no array dimension

该函数应称为

int result = maketable(&table, number_of_elements);

定义

int maketable (struct hash_entry ***table, size_t size)
{
  int r = 0;

  // sizeof **table == sizeof (struct hash_entry *)
  *table = malloc(sizeof **table * size);
  // *ALWAYS* check the result of malloc()
  if (*table)
  {
    size_t i;
    for (i = 0; i < size; i++)
      (*table)[i] = NULL;
    r = 1;
  }
  return r;
}

编辑maketable示例中有一个错误;table在应用下标之前需要取消引用,即(*table)[i]. 我们将下标应用于table 指向 的内容,而不是表指针本身。

很抱歉有任何混淆。

于 2010-01-26T23:27:04.480 回答