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

发布于 2024-08-18 21:49:09 字数 621 浏览 7 评论 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 返回时,我不会丢失任何内容,对吧?

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

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

I want to 'construct' (read: malloc and memset) my hashtable in c. To do this, I created a function as follows:

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;

}

Given that table will have been declared as

struct hash_entry **table[size]

before entering this code, I won't lose anything when I return from maketable, right?

EDIT:
Does passing table into maketable() ensure that as long as I change the data that table points to, the changes will be preserved?

EDIT II:
I am trying to allocate an array of pointers to pointers to hash_entries

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

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

发布评论

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

评论(3

尹雨沫 2024-08-25 21:49:09

您的代码正在分配给本地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]< /code> 确实是您想要的,您需要告诉我们您的 maketable() 函数实际上应该做什么(例如,您想要动态分配的“数组”作为该表中的元素之一吗?

Your code is assigning to the local table variable, the caller is not affected. This results in a memory leak.

Outside the function, you have declared table as an array of pointer to pointers of struct hash_entry - I'm guessing you rather just want an array of pointers to struct hash entries.

If you actually declare table as an array, there's no need to malloc that space. You just need a loop to set every element in it to NULL (Don't memset each element to zeroes).

If the goal is to allocate the entire table, this is perhps what you're looking for:

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

call it like

maketable(&table,100);

I'd rather make that return the table like so:

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

if the declaration struct hash_entry **table[size] is really what you want, you need to tell us what your maketable() function actually is supposed to do (e.g. do you want to a dynamically allocated 'array' as one of the elements in that table ?

绝影如岚 2024-08-25 21:49:09

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

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

You will need to assign the result of malloc to * table - otherwise it won't be visible outside the function.

Also, the typical way of using this is to declare a pointer to the hashtable and pass the address of that pointer into the function.

冬天旳寂寞 2024-08-25 21:49:09

不,你们的类型不匹配。

您是否正在尝试分配一个哈希条目表(即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

函数应该是< em>称为为

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指向的内容,而不是表指针本身。

抱歉造成任何混乱。

No. Your types don't match up.

Are you trying to allocate a table of hash entries (i.e., the type of table[i] is struct hash_entry), a table of pointers to hash_entries (i.e., the type of table[i] is struct hash_entry *), or something else? Based on how your code reads, I'm assuming the first case, but let me know if that's wrong.

Assuming you're dynamically allocating a table of struct hash_entry, your declaration of the table in the caller should be

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

the function should be called as

int result = maketable(&table, number_of_elements);

and defined as

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

A couple of things to point out. First of all, don't cast the result of malloc(). As of C89, you don't need to, and the cast will supress a diagnostic if you forget to include stdlib.h or otherwise don't have a prototype for malloc() in scope. Secondly, you can use the sizeof operator on objects instead of types. This can help reduce some maintenance headaches (i.e., if you change the type of table in the parameter list, you don't have to change the sizeof calls along with it).

Finally, note that the address of table is being passed to the function; since we're trying to write to a pointer value, we must pass a pointer to that pointer.

If you were attempting to create a table of pointers to struct hash_entry, the code is mostly the same, just an extra level of indirection:

your declaration of the table in the caller should be

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

the function should be called as

int result = maketable(&table, number_of_elements);

and defined as

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

EDIT There was a bug in the maketable examples; table needs to be dereferenced before applying the subscript, i.e., (*table)[i]. We're applying the subscript to what table points to, not the table pointer itself.

Sorry for any confusion.

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