我可以在c中指定类似Java的“构造函数”吗?

时间:2010-01-26 22:59:30

标签: c constructor struct malloc memset

我想在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返回时,我不会丢失任何东西,对吗?

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

编辑II: 我正在尝试为指向hash_entries

的指针分配一个指针数组

3 个答案:

答案 0 :(得分:4)

您的代码分配给本地table变量,调用方不受影响。这会导致内存泄漏。

在函数外部,你已经将table声明为指向struct hash_entry指针的指针数组 - 我猜你只是想要一个指向struct hash条目的指针数组。

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

如果目标是分配整个表格,那么这就是您正在寻找的内容:

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()函数究竟应该做什么(例如你想要一个动态分配的'数组'作为其中一个元素在那张桌子上?

答案 1 :(得分:2)

您需要将malloc的结果分配给* table - 否则在函数外部将无法显示。

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

答案 2 :(得分:1)

没有。您的类型不匹配。

您是否尝试将哈希条目表(即table[i]的类型为struct hash_entry),指针表分配给hash_entries(即类型) table[i]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 指向的内容,而不是表指针本身。

对不起有任何困惑。