我在使用 valgrind 时收到错误:
==696839== HEAP SUMMARY:
==696839== in use at exit: 136 bytes in 1 blocks
==696839== total heap usage: 6 allocs, 5 frees, 12,624 bytes allocated
==696839==
==696839== 136 bytes in 1 blocks are definitely lost in loss record 1 of 1
==696839== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==696839== by 0x109A35: insert_word_into_table (dictionary.c:57)
==696839== by 0x109BD9: dict_insert (dictionary.c:82)
==696839== by 0x109606: main (spell_check.c:91)
==696839==
==696839== LEAK SUMMARY:
==696839== definitely lost: 136 bytes in 1 blocks
==696839== indirectly lost: 0 bytes in 0 blocks
==696839== possibly lost: 0 bytes in 0 blocks
==696839== still reachable: 0 bytes in 0 blocks
==696839== suppressed: 0 bytes in 0 blocks
这是发生错误的函数的基本、最小版本;我正在迭代一系列链表。
int insert_word_into_table(table_t *table, const char *word){
int hsh_code = hash_code(word);
int duplicateWordFlag = 0;
//initialize the new node for the word
list_node_t *newNode = malloc(sizeof(list_node_t));//line 57 that error is referring to
//printf("%lu", sizeof(list_node_t)); checking the size, it is 136 bytes
if (table->array[hsh_code] == NULL) {//if nothing is in the array
table->array[hsh_code] = newNode;
table->array[hsh_code]->next = NULL;
strcpy(table->array[hsh_code]->word, word);
} else {//if there is a node there
list_node_t* i = table->array[hsh_code];
while (i->next != NULL) {
if (strcmp(word, i->word) == 0){
duplicateWordFlag = -1;
}
i = i->next;
}
i->next = malloc(sizeof(list_node_t));
strcpy(i->next->word, word);
i->next->next = NULL;
}
return duplicateWordFlag;
}
我尝试释放函数中分配的两个位置的内存,但这也不起作用。我有一点困惑;如果内存是在函数中分配的,那么当程序离开该函数时,它不会被释放,还是在堆上?无论如何,在整个程序结束时,我都会释放整个链表数组的内存,我认为这会处理它。
任何建议或想法都会很棒。谢谢!
如果在函数中分配了内存,那么当程序离开该函数时,它是否没有被释放,还是在堆上?
动态分配的内存(例如通过
malloc
)将保持分配状态,直到被显式释放。从这个意义上说,“堆”不是一个 C 语言概念,但通常是的,内存分配在有意义的系统上的堆上。
无论如何,在整个程序结束时,我都会释放整个链表数组的内存,我认为这会处理它。
有些内存没有以这种方式释放是内存泄漏的迹象,我认为这正是您希望 Valgrind 为您检测到的情况。在我看来,问题在于,仅当
table->array[hsh_code] == NULL
计算结果为 1 时,您在dictionary.c:57 分配的节点才会链接到列表中。否则,函数将返回而不释放它或保留任何指向它的指针。这是典型的内存泄漏。
请注意,在另一个分支中,您分配另一个节点。看来您可以使用已经分配的那个,这可能会解决您的泄漏问题。