2009-05-06 16 views
0

更新の質問は、私はこれは私がやったことですC.でハッシュテーブルを作ることに取り組んでいるなぜこのコードはCでメモリを割り当てないのですか?

Memory allocation problem in 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がされ、私は正しい道に行くと思うけど

リスト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の専門家ではありません。あなたがListPtrののcontigousブロックを割り当てているが、あなたは実際にそれらの構造にすべての構造だけではなく、ポインタ(ListPtr)のためのスペースを割り当てたい

+0

貼り付けたコードが不一致の数がある - エクストラ)createHashTable中をcreateHashTableの呼び出しで実際に必要な引数より多くの引数が必要です。これは実行しているのと同じコードですか?あなたがあなたのポインタを隠さなければ、あなたの問題の多くが見えるようになると思います。 – bdonlan

+2

つまり、ListPtrとNodePtrを削除しないでください。 – GManNickG

+0

おっと!私はちょうどそれをきれいに見せたいと思って、それを台無しにしました。ごめんなさい。 –

答えて

0

calloc(capacity, sizeof(List)); 

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

2
calloc(capacity, sizeof(ListPtr) 

は、私がここでの問題の全体のホストがあると思い

calloc(capacity, sizeof(List) 
2

でなければなりません。あなたはエラーが表示されていないので、私はカップルを挙げます:

  • ハッシュ=(HashTablePtr)malloc(sizeof(HashTablePtr *)); - HashTable **のサイズを4バイトに割り当てると、基になるオブジェクトのサイズを割り当てる必要があります。
  • ListPtr mylist =(ListPtr *)calloc(capacity、sizeof(ListPtr)); - ここでも、基になるリストオブジェクトではなくポインタのサイズを割り当てています。
  • HashTablePtr createHashTable(unsigned int capacity)){ - おそらく余分な括弧と矛盾した数のパラメータでコンパイルエラーが発生しています。
+0

申し訳ありませんが、私は見た目をきれいにしていたので、それを台無しにしました。私はコンパイルエラーを取得していません。 –

2

個人的には、私は特に初心者のときには、typedefを使用することの巨大なファンではありません。私はそれが部分的にあなたを混乱させるかもしれないと思う。あなたは常に彼らはあまりにも言及しているものを調べる必要がありますので、読んで、あなたのコードが難しくなり、多くのtypedefに使用

typedef struct hashtable * HashTablePtr; 

:あなたはより良いようなものを避けています。

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

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

c99 std

malloc manpage

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); 
関連する問題