适当的内存分配

时间:2008-12-16 08:42:51

标签: c memory struct hashtable allocation

我有以下结构:

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个条目的哈希表,但它不起作用!谁能帮我?我真的很感激!

4 个答案:

答案 0 :(得分:9)

预先分配所有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结构来保存表
  • 使用指定的容量初始化它的大小
  • 分配一个适当长度的存储桶指针数组
  • 确保每个存储桶指针都为NULL(使用memset()无法正确执行,因为假设“所有位为零”是NULL在内存中的显示方式是不安全的)
  • 尽可能使用sizeof,但不使用类型,因此不使用括号
  • 不会转换malloc()的返回值,因为在C
  • 中这绝不是一个好主意
  • 不检查malloc()的返回值,当然你应该在实际代码中执行

需要第二个函数来进行实际的哈希插入,然后需要分配一个新的桶,从密钥计算哈希值,在哈希表的数组中选择正确的位置,并在那里插入新的条目

答案 1 :(得分:0)

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

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中有点生锈,所以带上一粒盐。

答案 2 :(得分:0)

不完全。假设这是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;
 }

编辑:我把我的水桶*桌子固定到水桶**

EDIT2:我已经摆脱了memset并为malloc添加了错误检查。

答案 3 :(得分:0)

你的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;