Valgrind 新手,似乎无法让它开心
Valgrind newbie, can't seem to make it happy
我正在学习 CS50 在线课程,手头的任务是将字典加载到内存中(我使用的是链式哈希 table 数据结构),并检查一个字典的内容文本文件对照字典中的单词。我写了一个 load() 函数来加载字典文件并将每个单词存储到内存中。加载所有单词时函数 returns 为真。 Valgrind 显示没有内存泄漏。问题是我有很多 read/write 错误。它帮助我查明它们似乎来自哪里,我一直在搜索互联网,但似乎无法弄清楚它的正面或反面。
相关代码如下:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASH_SIZE 10
#define LENGTH 45
typedef struct node
{
char* word;
struct node* next;
} node;
// Globals
node* hashTable[HASH_SIZE];
unsigned int dictionary_size = 0;
/**
* Loads dictionary into memory. Returns true if successful else false.
**/
bool load(const char* dictionary)
{
// Initialize variables
char currentWord[LENGTH + 1];
int tableIndex;
// Open dictionary
FILE* dict = fopen(dictionary, "r");
if (dict == NULL)
return false;
while(fscanf(dict, "%s", currentWord) == 1)
{
// Get hash value of word
tableIndex = hash(currentWord);
// Initialize new node
node* newNode = malloc(sizeof(node));
newNode->word = malloc((strlen(currentWord) + 1) * sizeof(char));
if (newNode == NULL || newNode->word == NULL)
{
printf("Error: Out of memory\n");
return false;
}
// Copy word into new node
strcpy(newNode->word, currentWord);
newNode->next = NULL;
// If no collision, hash word into head of list
if (hashTable[tableIndex] == NULL)
hashTable[tableIndex] = newNode;
// Create a pointer and move down list
else
{
node* ptrNode = hashTable[tableIndex];
while (ptrNode->next != NULL)
ptrNode = ptrNode->next;
// Append node to end of linked list
ptrNode->next = newNode;
}
// Increase dictionary size
dictionary_size++;
// Free word member before actual node
free(newNode->word);
free(newNode);
}
// Close dictionary and return true
fclose(dict);
return true;
}
还有我的 Valgrind:
==32487== Invalid read of size 4
==32487== at 0x8048989: load (my_new_test.c:120)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== Address 0x423b30c is 4 bytes inside a block of size 8 free'd
==32487== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86- linux.so)
==32487== by 0x80489D3: load (my_new_test.c:132)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487==
==32487== Invalid write of size 4
==32487== at 0x80489AA: load (my_new_test.c:124)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== Address 0x423b30c is 4 bytes inside a block of size 8 free'd
==32487== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32487== by 0x80489D3: load (my_new_test.c:132)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487==
==32487== Invalid read of size 4
==32487== at 0x8048999: load (my_new_test.c:121)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== Address 0x423bb24 is 4 bytes inside a block of size 8 free'd
==32487== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32487== by 0x80489D3: load (my_new_test.c:132)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== HEAP SUMMARY:
==32487== in use at exit: 0 bytes in 0 blocks
==32487== total heap usage: 286,183 allocs, 286,183 frees, 2,584,308 bytes allocated
==32487==
==32487== All heap blocks were freed -- no leaks are possible
==32487==
==32487== For counts of detected and suppressed errors, rerun with: -v
==32487== ERROR SUMMARY: 10000000 errors from 3 contexts (suppressed: 0 from 0)
我对 Valgrind 还是很陌生,但从我收集到的信息来看,我的问题似乎在 else 语句中,主要是创建的指针 (node* ptrNode)。谁能看到我看不到的东西?任何帮助将不胜感激!
问题很可能是这两行:
free(newNode->word);
free(newNode);
您刚刚将节点添加到您的散列-table,然后您立即释放它,使散列-table 中的指针无效,因为它们现在指向已释放的数据。
我正在学习 CS50 在线课程,手头的任务是将字典加载到内存中(我使用的是链式哈希 table 数据结构),并检查一个字典的内容文本文件对照字典中的单词。我写了一个 load() 函数来加载字典文件并将每个单词存储到内存中。加载所有单词时函数 returns 为真。 Valgrind 显示没有内存泄漏。问题是我有很多 read/write 错误。它帮助我查明它们似乎来自哪里,我一直在搜索互联网,但似乎无法弄清楚它的正面或反面。
相关代码如下:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASH_SIZE 10
#define LENGTH 45
typedef struct node
{
char* word;
struct node* next;
} node;
// Globals
node* hashTable[HASH_SIZE];
unsigned int dictionary_size = 0;
/**
* Loads dictionary into memory. Returns true if successful else false.
**/
bool load(const char* dictionary)
{
// Initialize variables
char currentWord[LENGTH + 1];
int tableIndex;
// Open dictionary
FILE* dict = fopen(dictionary, "r");
if (dict == NULL)
return false;
while(fscanf(dict, "%s", currentWord) == 1)
{
// Get hash value of word
tableIndex = hash(currentWord);
// Initialize new node
node* newNode = malloc(sizeof(node));
newNode->word = malloc((strlen(currentWord) + 1) * sizeof(char));
if (newNode == NULL || newNode->word == NULL)
{
printf("Error: Out of memory\n");
return false;
}
// Copy word into new node
strcpy(newNode->word, currentWord);
newNode->next = NULL;
// If no collision, hash word into head of list
if (hashTable[tableIndex] == NULL)
hashTable[tableIndex] = newNode;
// Create a pointer and move down list
else
{
node* ptrNode = hashTable[tableIndex];
while (ptrNode->next != NULL)
ptrNode = ptrNode->next;
// Append node to end of linked list
ptrNode->next = newNode;
}
// Increase dictionary size
dictionary_size++;
// Free word member before actual node
free(newNode->word);
free(newNode);
}
// Close dictionary and return true
fclose(dict);
return true;
}
还有我的 Valgrind:
==32487== Invalid read of size 4
==32487== at 0x8048989: load (my_new_test.c:120)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== Address 0x423b30c is 4 bytes inside a block of size 8 free'd
==32487== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86- linux.so)
==32487== by 0x80489D3: load (my_new_test.c:132)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487==
==32487== Invalid write of size 4
==32487== at 0x80489AA: load (my_new_test.c:124)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== Address 0x423b30c is 4 bytes inside a block of size 8 free'd
==32487== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32487== by 0x80489D3: load (my_new_test.c:132)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487==
==32487== Invalid read of size 4
==32487== at 0x8048999: load (my_new_test.c:121)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== Address 0x423bb24 is 4 bytes inside a block of size 8 free'd
==32487== at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32487== by 0x80489D3: load (my_new_test.c:132)
==32487== by 0x804873D: main (my_new_test.c:53)
==32487== HEAP SUMMARY:
==32487== in use at exit: 0 bytes in 0 blocks
==32487== total heap usage: 286,183 allocs, 286,183 frees, 2,584,308 bytes allocated
==32487==
==32487== All heap blocks were freed -- no leaks are possible
==32487==
==32487== For counts of detected and suppressed errors, rerun with: -v
==32487== ERROR SUMMARY: 10000000 errors from 3 contexts (suppressed: 0 from 0)
我对 Valgrind 还是很陌生,但从我收集到的信息来看,我的问题似乎在 else 语句中,主要是创建的指针 (node* ptrNode)。谁能看到我看不到的东西?任何帮助将不胜感激!
问题很可能是这两行:
free(newNode->word);
free(newNode);
您刚刚将节点添加到您的散列-table,然后您立即释放它,使散列-table 中的指针无效,因为它们现在指向已释放的数据。