正确的内存分配

发布于 2024-07-10 00:24:17 字数 357 浏览 7 评论 0原文

我有以下结构:

typedef struct bucket {
    char *key;
    ENTRY *data;
    struct bucket *next;
} bucket;

typedef struct {
    size_t size;
    bucket **table;
} hash_table;

但我不知道如何为此分配内存。 我尝试过:

hash_table* ht = malloc(sizeof(hash_table)*101);

为了创建 101 个条目的哈希表,但它不起作用! 谁能帮我? 我真的很感激!

I have the following construction:

typedef struct bucket {
    char *key;
    ENTRY *data;
    struct bucket *next;
} bucket;

typedef struct {
    size_t size;
    bucket **table;
} hash_table;

But I have no idea how to allocate memory for that. I tried:

hash_table* ht = malloc(sizeof(hash_table)*101);

in order to create a hashtable for 101 entries but it din't work! Can anyone help me? I would really appreciate it!

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

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

发布评论

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

评论(4

鹊巢 2024-07-17 00:24:17

预先分配所有 101 个(或任意数量)存储桶是没有意义的,通常在向表中插入新数据时一次分配一个存储桶。

预分配哈希数组确实有意义,该数组具有固定大小,但这是一个存储桶指针数组,而不是存储桶数组,因此有些的答案是错误的。

你会有这样的事情,创建一个空的哈希表,带有固定大小的存储桶数组:

hash_table * hash_table_new(size_t capacity)
{
  size_t i;

  hash_table *t = malloc(sizeof *t);
  t->size = capacity;
  t->bucket = malloc(t->size * sizeof *t->bucket);
  for(i = 0; i < t->size; i++)
    t->bucket[i] = NULL;
  return t;
}

此代码:

  • 分配一个 hash_table 结构来保存该表
  • 用指定的容量初始化它的大小
  • 分配适当的存储桶指针数组length
  • 确保每个存储桶指针为 NULL(这不能用 memset() 正确完成,因为假设“所有位为零”是 NULL 在内存中的查找方式是不安全的)
  • 尽可能使用 sizeof ,但不在类型上,因此没有括号
  • 不转换 malloc() 的返回值,因为这在 C 中从来都不是一个好主意
  • 不检查 malloc() 的返回值,当然,您应该在实际代码中执行此

操作需要第二个函数来执行实际的哈希插入,然后需要分配一个新的存储桶,根据键计算哈希值,在哈希表的数组中选择正确的位置,然后在那里插入新条目。

It doesn't make sense to allocate all 101 (or however many) buckets upfront, you'd typically allocate them one at a time, when inserting new data into the table.

It does make sense to pre-allocate the hash array, which will have a fixed size, but that is an array of bucket pointers, not an array of buckets, so some of the answers are wrong.

You'd have something like this, to create a an empty hash table, with a fixed-size bucket array:

hash_table * hash_table_new(size_t capacity)
{
  size_t i;

  hash_table *t = malloc(sizeof *t);
  t->size = capacity;
  t->bucket = malloc(t->size * sizeof *t->bucket);
  for(i = 0; i < t->size; i++)
    t->bucket[i] = NULL;
  return t;
}

This code:

  • Allocates a hash_table structure to hold the table
  • Initializes it's size with indicated capacity
  • Allocates an array of bucket pointers of the proper length
  • Makes sure each bucket pointer is NULL (which cannot properly be done with memset(), as it's not safe to assume that "all bits zero" is the way NULL looks in memory)
  • Uses sizeof whenever possible, but not on types, so no parenthesis
  • Doesn't cast the return value of malloc(), since that is never a good idea in C
  • Doesn't check the return value of malloc(), of course you should do that in real code

A second function would be needed to do an actual hash insert, which will then need to allocate a new bucket, compute the hash value from the key, pick the proper location in the hash table's array, and insert the new entry there.

笑咖 2024-07-17 00:24:17

不完全的。 假设这是 C,您可能想要创建一个函数:

 hash_table* init_table(size_t size) {
     size_t i;
     hash_table* ht = (hash_table*)malloc(sizeof(hash_table));
     if (ht == NULL) return NULL;
     ht->size = size;
     ht->table = (bucket**)malloc(sizeof(bucket*)*size);
     if (ht->table == NULL) {
         free(ht);
         return NULL;
     }
     for (i = 0; i < size; ++i) {
         ht->table[i] = NULL;
     }
     return ht;
 }

您可能需要该结构中的一些其他字段。

如果你想变得狡猾,并且从不重新分配存储桶,你可以这样做:

 hash_table* init_table(size_t size) {
     hash_table* ht = (hash_table*)malloc(sizeof(hash_table)+sizeof(bucket)*size);
     if (ht == NULL) return NULL;
     ht->size = size;
     ht->table = (bucket**)(ht+1);
     for (i = 0; i < size; ++i) {
         ht->table[i] = NULL;
     }
     return ht;
 }

编辑:我将我的存储桶*表固定为存储桶**

编辑2:我已经摆脱了memsets并添加了malloc的错误检查。

Not quite. Assuming this is C, you probably want to make a function:

 hash_table* init_table(size_t size) {
     size_t i;
     hash_table* ht = (hash_table*)malloc(sizeof(hash_table));
     if (ht == NULL) return NULL;
     ht->size = size;
     ht->table = (bucket**)malloc(sizeof(bucket*)*size);
     if (ht->table == NULL) {
         free(ht);
         return NULL;
     }
     for (i = 0; i < size; ++i) {
         ht->table[i] = NULL;
     }
     return ht;
 }

You might need some other fields in that struct.

If you wanted to be tricky, and never realloc the bucket, you can do this:

 hash_table* init_table(size_t size) {
     hash_table* ht = (hash_table*)malloc(sizeof(hash_table)+sizeof(bucket)*size);
     if (ht == NULL) return NULL;
     ht->size = size;
     ht->table = (bucket**)(ht+1);
     for (i = 0; i < size; ++i) {
         ht->table[i] = NULL;
     }
     return ht;
 }

EDIT: I fixed my bucket* table's to bucket**

EDIT2: I've gotten rid of the memsets and added error checking for malloc.

转身以后 2024-07-17 00:24:17

hash_table 始终只有 sizeof(hash_table) 字节大。 table 元素是一个指向 bucket 元素的指针数组的指针。 所以你需要这样的东西:

hash_table* ht = malloc(sizeof(hash_table));
ht->size = 101;
ht->table = malloc(sizeof(bucket*)*ht->size);

但我怀疑可能有一些随之而来的初始化方法,然后你可以做这样的事情:

hash_table* ht = alloc_hash_table(101);

不管怎样,我对 C 有点生疏,所以把这个与谷物一起考虑盐。

The hash_table will always be only sizeof(hash_table) bytes big. The table element is a pointer to an array of poiinters to bucket elements. So you'd need something like this:

hash_table* ht = malloc(sizeof(hash_table));
ht->size = 101;
ht->table = malloc(sizeof(bucket*)*ht->size);

But I suspect that there may be some initialization method that comes with that, and you could then do something like this:

hash_table* ht = alloc_hash_table(101);

Anyway, I'm kind of rusty in C, so take this with a grain of salt.

圈圈圆圆圈圈 2024-07-17 00:24:17

你的 typedef 有一些问题。 假设您使用 MSVC。

声明此处类型的简单方法如下:

此 typedef 包括 _type {} 类型,*ptype; 格式同时声明类型和指向自定义类型的指针。 如果您在 hash_table 中看到,您可以使用 pbucket *table,它消除了代码中的额外 ***,并且可以在进行动态分配时提供帮助(帮助您清楚分配的内容等。 )。 你原来的 typedef,如果你看起来有 typedef struct bucket {} bucket;,你至少需要修改你指定 typedef 时的两个“bucket”名称之一。

如果您使用 C++ 构建设置,您还需要进行强制转换,如果使用纯 C,则可能不需要强制转换,因此您的 malloc 行将是(我进行了以下 typedef 更改);

hash_table* ht = (phash_table) malloc(sizeof(hash_table)*101);

不管怎样,这个片段应该适合你;

typedef struct _bucket {    
    char *key;    
    void *data;    
    _bucket *next;
} bucket, *pbucket;

typedef struct _hash_table {    
    size_t size;    
    pbucket *table;
}hash_table, *phash_table;

There's a few things worong with your typedef's. Assuming your using MSVC.

An easy way to declare the types you have here would be something like;

This typedef includes the _type {} type, *ptype; format which declares the type and the pointer to your custom type all at the same time. If you see down in hash_table, your are able to use pbucket *table, which eliminates the extra *** in your code and can help when doing dynamic allocation (help so mucah as to keep your head straight about what your allocating etc..). Your original typedef, if you look had typedef struct bucket {} bucket;, you need to at least modify one of the two "bucket" names you have there when you specify your typedef.

You also need to cast if your using C++ build settings, if using plain C you may not need the cast, so your malloc line would be (with the following typedef changes I made);

hash_table* ht = (phash_table) malloc(sizeof(hash_table)*101);

Either way, this snippet should work for you;

typedef struct _bucket {    
    char *key;    
    void *data;    
    _bucket *next;
} bucket, *pbucket;

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