0

更新された質問はこちら

HashTable のメモリ割り当ての問題

私は C で HashTable の作成に取り組んでいます。これが私が行ったことです。私は正しい道を進んでいると思いますが、そうしようとすると

main.c

HashTablePtr hash;
hash = createHashTable(10);
insert(hash, "hello");
insert(hash, "world");

HashTable.c

    HashTablePtr createHashTable(unsigned int capacity){
    HashTablePtr hash;
    hash = (HashTablePtr) malloc(sizeof(HashTablePtr));
    hash->size = 0;
    hash->capacity = capacity;
    ListPtr mylist = (ListPtr)calloc(capacity, sizeof(ListPtr)); /* WHY IT DOESN'T ALLOCATE MEMORY FOR mylist HERE?? */
    mylist->head = NULL;
    mylist->size = 0;
    mylist->tail = NULL;    
    hash->list = mylist;  
    return hash;

ListPtr は LinkedList ptr です

List.h

typedef struct list List;
typedef struct list * ListPtr;

struct list {
    int size;
    NodePtr head;
    NodePtr tail;
};
...
...

HashTable.h

    typedef struct hashtable * HashTablePtr;
    typedef struct hashtable HashTable;
    struct hashtable {
        unsigned int capacity;
        unsigned int size;
        ListPtr *list;
        unsigned int (*makeHash)(unsigned int, void *);
    };
...
...

デバッガーを実行すると、myList にメモリが割り当てられていません。上記の例では、私の試みはそれを 10 個のリストの配列にすることです。

これを解決するのを手伝ってください。

それが助けになるなら、私はCの専門家ではありません。

4

4 に答える 4

2
calloc(capacity, sizeof(ListPtr)

する必要があります

calloc(capacity, sizeof(List)
于 2009-05-06T04:21:07.477 に答える
2

ここにはたくさんの問題があると思います。発生したエラーは含まれていません。いくつかリストします。

  • hash =(HashTablePtr)malloc(sizeof(HashTablePtr *)); -4バイトのHashTable**のサイズを割り当てているので、基になるオブジェクトのサイズを割り当てる必要があります。
  • ListPtr mylist =(ListPtr *)calloc(capacity、sizeof(ListPtr)); -繰り返しになりますが、基になるリストオブジェクトではなく、ポインタのサイズを割り当てています。
  • HashTablePtr createHashTable(unsigned int capacity)){-余分な括弧と一貫性のない数のパラメーターを使用して、ここでコンパイルエラーが発生している可能性があります。
于 2009-05-06T04:23:01.157 に答える
2

個人的には、特に初心者の場合は、typedef を使用することはあまり好きではありません。それが部分的にあなたを混乱させているのかもしれません。次のようなことは避けた方がよいでしょう:

typedef struct hashtable * HashTablePtr;

多くの typedef を使用すると、それらが参照しているものも常に検索する必要があるため、コードが読みにくくなります。

主な問題は、ハッシュテーブル/リスト ポインターのサイズに対してメモリを割り当てていて、それらの尊重される構造体のサイズに対してメモリを割り当てていなかったことです。以下のコードはこれをよく示していると思います。また、割り当てが機能したかどうかも確認する必要があります。malloc、calloc、realloc の場合。失敗すると NULL を返します。これが発生し、このケースをチェックしないと、segfault エラーが発生し、プログラムがクラッシュします。

また、c99 標準に従い、すべての変数宣言を関数の先頭に置きます。

c99標準

mallocマンページ

struct hashtable *
createHashTable(unsigned int capacity){
    struct hashtable *hash;
    struct list *mylist;

    /* You want to allocate size of the hash structure not the size of a pointer. */
    hash = malloc(sizeof(struct hashtable)); 
    // always make sure if the allocation worked.
    if(hash == NULL){
        fprintf(stderr, "Could not allocate hashtable\n");
        return NULL;
    }

    hash->size = 0;
    hash->capacity = capacity;

    /* Unless you need the memory to be zero'd I would just use malloc here
     * mylist = calloc(capacity, sizeof(struct list)); */
    mylist = malloc(capacity * sizeof(struct list));
    if(mylist == NULL){
        fprintf(stderr, "Could not allocate list\n");
        free(hash); /* free our memory and handle the error*/
        return NULL;
    }

    mylist->head = NULL;
    mylist->size = 0;
    mylist->tail = NULL;    
    hash->list = mylist;

    return hash;
}

また、ハッシュテーブルを解放する前にリストを解放することを忘れないでください:

free(myhash->list);
free(myhash);
于 2009-05-06T12:18:29.063 に答える
0

ListPtrの連続したブロックを割り当てていますが、実際には、これらの構造へのポインター(ListPtr)だけでなく、すべての構造にスペースを割り当てたいと考えています。

calloc(capacity, sizeof(List));

ポインタを隠さないというgmanのコメントに同意します。List *Cでコーディングするとき、私はaをとしてtypdefすることはありませんListPtr。コードを理解しにくくします。

于 2009-05-06T04:20:22.300 に答える