数日前、私はこの質問を投稿しました、そして、誰もが私に使用するように提案しましたvoid*
、それは私がしました。それらのいくつかは私が世話をする必要があるいくつかのことも指摘したと思いますが、それらが正確に何であったかはわかりません。しかし、私はこれに関していくつかの問題を抱えています...
非常に大きいコードをすべて投稿するのではなく、重要だと思うものを投稿します。うまくいけば、あなたが私を助けてくれるのに十分です。
私のハッシュテーブル構造は次のようなものです。
typedef void * HashKey;
typedef void * HashValue;
typedef struct sHashItem {
HashKey key;
HashValue value;
char status;
} HashItem;
typedef struct sHashTable {
HashItem *items;
int count;
float load;
int size;
Bool (*compare)(HashKey, HashKey);
unsigned (*hash)(void *);
} HashTable;
私の挿入関数の署名は次のようになります。
Bool hashInsert(HashTable * const table, HashKey key, HashValue value);
そして、その関数内のどこかで、ハッシュテーブルに空きバケットが見つかったら、次のようにします。
table->items[index].key = key;
table->items[index].value = value;
table->items[index].status = USED;
table->load = ++table->count / (float)table->size;
これにはいくつかの問題があります。
1)上記のように、フリーバケットの各キー/値ペアを、キー/値hashInsert
関数の引数として渡されたのと同じポインターに設定しているだけです。すでにお気づきかもしれませんが、これは問題を引き起こします...たとえば、次のようなことをします。
char str[50];
scanf("%s%*c", str);
hashInsert(t1, (HashKey)str, (HashValue)5);
scanf("%s%*c", str);
hashInsert(t1, (HashKey)str, (HashValue)3);
また、入力が「KeyA」、次に「KeyB」の場合、両方のバケットキーとして「KeyB」が使用されます。キーだけでなく値にも同じことが当てはまります。これは、どのデータ型でもコードを完全にモジュール化するため、基本的に同じ型であるためです。
どうすればこれを解決できますか?
私の最初は、それを使用strdup(str)
して関数に渡すことhashInsert
です。それで問題は解決します。また、これはメインコードで処理されたmalloc()
ため、値として渡す必要のある他のデータ型にも簡単に使用できます(キーはおそらく常に文字列または整数になります)。
しかし、この解決策には別の問題があります...
2)この割り当てられたメモリをどのように解放する必要がありますか?確かに、それは「ハッシュテーブルモジュールプログラマー」ではなく「メインプログラマー」によって割り当てられたので、「メインプログラマー」はメインコードでそれを解放する必要がありますよね?しかし、それは私にはモジュラーコードのようには見えません。
私のコードにはhashDestroy
、割り当てられたすべてのメモリを解放する機能もあります。しかし、どうすればこの関数を使用してすべてを解放できますか?すべてのキー/値を繰り返し処理して使用することはできません。そもそもfree()
それらの一部はmalloc'd
プログラマーによるものではなく、解放する必要がないためです。
hashDestroy
解放しなければならないものと解放してはいけないものをどのように見つけることができますか?
3)最後に、この問題をミックスに入れることもできると思います...ポイント1で、私の提案は、その特定の問題を使用strdup()
またはmalloc
「修正」することでしたが、それはあまりモジュール化されていないように見えます私に。このメモリ割り当ては、「メインプログラマ」によるメインコードではなく、ハッシュテーブルモジュールコードで行う必要があります。
私がこれを解決することをどのように提案しますか?つまり、データ型は何でもかまいません。を使用すると非常にstrdup()
役立ちますが、文字列に対してのみ機能します。特定の構造またはintだけにメモリを割り当てる必要がある場合はどうなりますか?
大きな投稿で申し訳ありませんが、これらの質問はすべて関連していると思います。私のCの知識はそれほど極端ではないので、それらを理解するのに助けが必要です。私は最近そのことを知りましvoid*
た...