Cは、それにもかかわらず、あなたがこのような何かをしたい場合、あなたが直接必要なものを提供していません:
あなたのハッシュテーブルは、二重リンクリストの固定サイズの配列であり、アイテムが常に割り当てられていることをOKであることを想像してみて/アプリケーション層で破壊される。これらの条件は、すべてのケースで機能するわけではありませんが、多くの場合、そのようになります。あなたはハッシュテーブルのロジックを実装する必要があり、これらの機能には
struct HashItemCore
{
HashItemCore *m_prev;
HashItemCore *m_next;
};
struct HashTable
{
HashItemCore m_data[256]; // This is actually array of circled
// double linked lists.
int (*GetHashValue)(HashItemCore *item);
bool (*CompareItems)(HashItemCore *item1, HashItemCore *item2);
void (*ReleaseItem)(HashItemCore *item);
};
void InitHash(HashTable *table)
{
// Ensure that user provided the callbacks.
assert(table->GetHashValue != NULL && table->CompareItems != NULL && table->ReleaseItem != NULL);
// Init all double linked lists. Pointers of empty list should point to themselves.
for (int i=0; i<256; ++i)
table->m_data.m_prev = table->m_data.m_next = table->m_data+i;
}
void AddToHash(HashTable *table, void *item);
void *GetFromHash(HashTable *table, void *item);
....
void *ClearHash(HashTable *table);
:次に、あなたは機能やprotototypesのこれらのデータ構造やスケッチを持っています。働いている間、彼らはスロットのインデックスを見つけるために、そして項目が同一であるかどうかを見つけるためにユーザ定義のコールバックを呼び出すでしょう。このテーブルのユーザは、彼らが使用するタイプのすべてのペアのために、独自の構造やコールバック関数を定義する必要があり
:項目は無効と周りに渡されますので、
struct HashItemK1V1
{
HashItemCore m_core;
K1 key;
V1 value;
};
int CalcHashK1V1(void *p)
{
HashItemK1V1 *param = (HashItemK1V1*)p;
// App code.
}
bool CompareK1V1(void *p1, void *p2)
{
HashItemK1V1 *param1 = (HashItemK1V1*)p1;
HashItemK1V1 *param2 = (HashItemK1V1*)p2;
// App code.
}
void FreeK1V1(void *p)
{
HashItemK1V1 *param = (HashItemK1V1*)p;
// App code if needed.
free(p);
}
このアプローチでは、型の安全性を提供することはありませんすべてのアプリケーション構造がHashItemCore
メンバで始まるものと仮定するポインタ。これは多種多様な手作りのものです。これは完璧ではないかもしれませんが、これはうまくいくでしょう。
私はテンプレートを使用してこのアプローチをC++で実装しました。しかし、あなたがC++のすべての想像を取り除くならば、要するに、私が上で述べたこととまったく同じになるでしょう。私は複数のプロジェクトでテーブルを使いましたが、それは魅力的でした。
マクロは* code *を繰り返すメカニズムです。それらはデータ構造ではありません。何らかの種類の動的メモリ割り当てに依存することなく、汎用のハッシュテーブルを実装することはできません。 –
さらに、データ構造にポインタが含まれていれば、動的割り当てについては何も言わないことになります。 –
@JohnBollingerあなたの最初のポイントは理にかなっています。投稿したリンクを見てみると、その意味が分かります。 Re:ポインタ...ポインタを含んでいるので、動的割り当てなしでマップに項目を追加しようとすると、それらの項目が正しい関数の外でそのマップを使用しようとすると無効になります。 – blackspirerider