[解決済み] テーブルの再ハッシュ化
2022-02-14 07:37:04
質問
古いテーブルを削除して、同じ内容の新しい大きなテーブルを作成することによって、テーブルをリハッシュしようとしています。reHash関数を作成しましたが、この関数がメモリリークを起こし、関数を実行するとプログラムがクラッシュしてしまいます。私のエラーを見つけることができません。
void HashMap::reHash()
{
int OldCapacity = cap;
cap = cap * 2 + 1; //set new capacity
Node** newHashTable = new Node*[cap]; //create a temporary table to hold info
for (int i = 0; i < cap; i++)
{
newHashTable[i] = nullptr;
}
const Node* n;
//fill in the new temp table with old info
for (int i = 0; i < OldCapacity; ++i)
{
n = HashTable[i];
while (n != nullptr)
{
//initialize new node
Node* nod = new Node;
nod->key = n->key;
nod->value = n->value;
nod->next = nullptr;
Node*& bucket = newHashTable[default_hash_function(n->key)/cap];
nod->next = bucket;
bucket = nod;
n = n->next;
}
}
// delete the links
for (int i = 0; i < OldCapacity; ++i)
{
Node *curr = HashTable[i];
Node *next;
while (curr != nullptr)
{
next = curr->next;
delete curr;
curr = next;
}
}
HashTable = newHashTable;
}
解決方法は?
根本的な漏れはこれだ。
HashTable = newHashTable;
古いポインタ配列を削除していませんね。こうなっているはずです。
delete [] HashTable;
HashTable = newHashTable;
また、ハッシュ関数のモジュロをテーブルサイズに対して正しく計算していないので、ハッシュテーブルが壊滅的なダメージを受けます。
これは
Node*& bucket = newHashTable[default_hash_function(tmp->key) / cap];
はこうでなければならない。
Node*& bucket = newHashTable[default_hash_function(tmp->key) % cap];
// note modulo operator -------------------------------------^
リハーサルサンスアロケーション
正直なところ。 なし の動的割り当てが必要なのは、新しいベッドを割り当てるときだけです。既存のノードを古いベッドから新しいベッドに移動させることで使用することができます。
void HashMap::reHash()
{
int OldCapacity = cap;
cap = cap * 2 + 1;
// allocate new bed. note: uses () to value-initialize nullptr entries
Node** newHashTable = new Node*[cap]();
//fill in the new temp table with old info
for (int i = 0; i < OldCapacity; ++i)
{
Node *n = HashTable[i];
while (n != nullptr)
{
// advance n *before* moving node to new hash bed
Node *tmp = n;
n = n->next;
// find the proper collision list pointer.
Node*& bucket = newHashTable[default_hash_function(tmp->key) % cap];
tmp->next = bucket;
bucket = tmp;
}
}
delete [] HashTable;
HashTable = newHashTable;
}
関連
-
[解決済み】coutはstdのメンバではない
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】'cout'は型名ではない
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】C++の余分な資格エラー
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)