ハッシュテーブルで検索することに基づいて単語のアナグラムを見つけるCで簡単なプログラムを書いています。私が持っているのはハッシュテーブルの配列です。ここで、単語は長さによってインデックスが付けられ、文字の合計によってハッシュされます。たとえば、a = 1、b=2などです。
私はまだCでの動的メモリ管理に精通しているので、この質問は非常に単純かもしれませんが、各ハッシュテーブル(およびその内部データ)にメモリを割り当ておよび割り当て解除する関数があります。
私はもともと単一のハッシュテーブルを使用してこのプログラムを作成しましたが、valgrindでプログラムを実行した後、メモリが正しく解放され、リークがないことがわかりました。ただし、ハッシュテーブルの配列を使用するようにプログラムを拡張すると、valgrindはリークの可能性を見つけ始めました(ただし、まだ到達可能であると報告されています)。配列内の各ハッシュテーブルは元々使用されていた割り当て解除関数を介して実行されていますが、なぜメモリがハッシュテーブルの配列で正しく解放されないのか混乱しています。
フルコードの要点フルコード
typedef struct Bucket Bucket;
typedef struct HashTable HashTable;
struct Bucket {
char* data;
Bucket *next;
};
struct HashTable {
int size;
Bucket **buckets;
};
int main(int argc, char const *argv[])
{
// Allocate memory for array of hash tables
HashTable** hash_array = (HashTable**) malloc(sizeof(HashTable*) * WORD_SIZE);
for(i = 0; i < WORD_SIZE; i++) {
hash_alloc(&hash_array[i], BUCKET_COUNT);
}
// Main logic here...
// Free memory
for(i = 0; i < WORD_SIZE; i++) {
hash_dealloc(hash_array[i]);
}
free(hash_array);
return 0;
}
ハッシュテーブル割り当て機能
void hash_alloc(HashTable** a, unsigned int size) {
*a = (HashTable*) malloc(sizeof(HashTable));
(*a)->buckets = (Bucket**) malloc(sizeof(Bucket*) * size);
(*a)->size = size;
}
ハッシュテーブルの割り当て解除機能
void hash_dealloc(HashTable* a) {
int i;
Bucket* current, *temp;
for(i = 0; i < a->size; i++) {
current = a->buckets[i];
while(current != NULL) {
temp = current;
free(temp->data);
current = current->next;
free(temp);
}
free(current);
}
free(a->buckets);
free(a);
}
ハッシュテーブル関数に追加
void add_to_hash_array(HashTable** a, char* data) {
// Removed some other logic for readability...
replace_str(data, "\n", "\0");
newNode->data = strdup(data);
newNode->next = currentTable->buckets[index];
currentTable->buckets[index] = newNode;
} else {
return;
}
}
Valgrindの出力
==39817== 261,120 bytes in 128 blocks are still reachable in loss record 5 of 7
==39817== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==39817== by 0x400A38: hash_alloc (main.c:73)
==39817== by 0x4008B0: main (main.c:39)
==39817==
==39817== 286,936 bytes in 31,553 blocks are still reachable in loss record 6 of 7
==39817== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==39817== by 0x4EBAD71: strdup (strdup.c:43)
==39817== by 0x400D4D: add_to_hash_array (main.c:141)
==39817== by 0x400914: main (main.c:51)
==39817==
==39817== 504,848 bytes in 31,553 blocks are still reachable in loss record 7 of 7
==39817== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==39817== by 0x400D16: add_to_hash_array (main.c:136)
==39817== by 0x400914: main (main.c:51)