valgrind 识别的内存分配错误
Memory Allocation error identified by valgrind
bool load(const char *dictionary)
{
// TODO
//create alphanumeric frequency trie from dictionary stored in temporary location
// open dictioary
FILE *dict = fopen(dictionary, "r");
if (dict == NULL)
{
return false;
}
//beggining of dictionary trie called 'root'
root = (trie*) malloc( sizeof(trie) );
if (root == NULL)
{
printf("error allocating memory to root for load");
return false;
}
//beggining of traversal node called 'current' and "attachment" to read/traverse root node
trie* current = NULL;
int a = (int)'a';
int z = (int)'z';
int cha = 0;
current = root;
//construct trie letter branches from ch (character) of single word-lines in dictionary
for ( char ch = fgetc(dict) ; EOF != ch ; ch = fgetc(dict) )
{
//set cursor letter to indexable value
if ( ch == '\'' )
{
cha = (z + 1) - a;
//printf("@%d ",cha);
}
else
{
cha = (ch - a);
//printf("%d ",cha);
}
//create or traverse existing letter branch for next letter ch in word-line
if( current->children[cha] == NULL && ) //(cha >= 0 && cha <=26) )
{
//printf("L");
current -> children[cha] = (trie*) malloc( sizeof(trie) );
current = current -> children[cha];
}
else //if ( cha >= 0 && cha <=26 )
{
current = current -> children[cha];
}
//for end of word-line in dictionary label as word and reset cursor node to root of dictionary trie (tree)
if ( ch == '\n' )
{
//printf("\n");
current->is_word = true;
wordcount++;
current = root;
//printf("%d", wordcount);
}
}
我的程序完全按照我正在处理的问题的指定进行编译和工作,但是我在下面的 if 语句开头没有通过 valgrind 测试。 Valgrind 测试 returns "Invalid read of size 8." 我希望我在下面提供的代码足以说明我在哪里侮辱了系统内存。
if( (cha >= 0 && cha <=26) && current->children[cha] == NULL )
{
current -> children[cha] = (trie*) malloc( sizeof(trie) );
current = current -> children[cha];
}
else if ( cha >= 0 && cha <=26 )
{
current = current -> children[cha];
}
下面还有我的trie节点的结构:
#define COUNT 27
typedef struct trie
{
bool is_word;
struct trie *children[COUNT];
}
trie;
//instantiation structures and variables
trie* root;
int wordcount = 0;
bool loaded;
//freetrie function prototype
void freetrie(trie* step);
以下是我如何为 trie 节点释放 malloc 内存:
void freetrie(trie* root)
{
for(int i = 0; i < 27; i++)
{
if (root -> children[i] != NULL)
{
freetrie(root -> children[i]);
}
}
free(root);
return;
}
bool unload(void)
{
// TODO
// free memory allocated by load for dictionary
trie* current = root;
freetrie(current);
return true;
}
行if( current->children[cha] == NULL && (cha >= 0 && cha <=26) )
仅在访问数组后执行索引边界检查,应该重写以验证索引在之前在该位置访问数组是否有效。摆脱幻数也是一个好主意:
#define TRIE_CHILDREN_COUNT 27
typedef struct trie
{
bool is_word;
struct trie *children[TRIE_CHILDREN_COUNT];
}
trie;
if((0 <= cha) && (cha < TRIE_CHILDREN_COUNT) && (NULL == current->children[cha]))
bool load(const char *dictionary)
{
// TODO
//create alphanumeric frequency trie from dictionary stored in temporary location
// open dictioary
FILE *dict = fopen(dictionary, "r");
if (dict == NULL)
{
return false;
}
//beggining of dictionary trie called 'root'
root = (trie*) malloc( sizeof(trie) );
if (root == NULL)
{
printf("error allocating memory to root for load");
return false;
}
//beggining of traversal node called 'current' and "attachment" to read/traverse root node
trie* current = NULL;
int a = (int)'a';
int z = (int)'z';
int cha = 0;
current = root;
//construct trie letter branches from ch (character) of single word-lines in dictionary
for ( char ch = fgetc(dict) ; EOF != ch ; ch = fgetc(dict) )
{
//set cursor letter to indexable value
if ( ch == '\'' )
{
cha = (z + 1) - a;
//printf("@%d ",cha);
}
else
{
cha = (ch - a);
//printf("%d ",cha);
}
//create or traverse existing letter branch for next letter ch in word-line
if( current->children[cha] == NULL && ) //(cha >= 0 && cha <=26) )
{
//printf("L");
current -> children[cha] = (trie*) malloc( sizeof(trie) );
current = current -> children[cha];
}
else //if ( cha >= 0 && cha <=26 )
{
current = current -> children[cha];
}
//for end of word-line in dictionary label as word and reset cursor node to root of dictionary trie (tree)
if ( ch == '\n' )
{
//printf("\n");
current->is_word = true;
wordcount++;
current = root;
//printf("%d", wordcount);
}
}
我的程序完全按照我正在处理的问题的指定进行编译和工作,但是我在下面的 if 语句开头没有通过 valgrind 测试。 Valgrind 测试 returns "Invalid read of size 8." 我希望我在下面提供的代码足以说明我在哪里侮辱了系统内存。
if( (cha >= 0 && cha <=26) && current->children[cha] == NULL )
{
current -> children[cha] = (trie*) malloc( sizeof(trie) );
current = current -> children[cha];
}
else if ( cha >= 0 && cha <=26 )
{
current = current -> children[cha];
}
下面还有我的trie节点的结构:
#define COUNT 27
typedef struct trie
{
bool is_word;
struct trie *children[COUNT];
}
trie;
//instantiation structures and variables
trie* root;
int wordcount = 0;
bool loaded;
//freetrie function prototype
void freetrie(trie* step);
以下是我如何为 trie 节点释放 malloc 内存:
void freetrie(trie* root)
{
for(int i = 0; i < 27; i++)
{
if (root -> children[i] != NULL)
{
freetrie(root -> children[i]);
}
}
free(root);
return;
}
bool unload(void)
{
// TODO
// free memory allocated by load for dictionary
trie* current = root;
freetrie(current);
return true;
}
行if( current->children[cha] == NULL && (cha >= 0 && cha <=26) )
仅在访问数组后执行索引边界检查,应该重写以验证索引在之前在该位置访问数组是否有效。摆脱幻数也是一个好主意:
#define TRIE_CHILDREN_COUNT 27
typedef struct trie
{
bool is_word;
struct trie *children[TRIE_CHILDREN_COUNT];
}
trie;
if((0 <= cha) && (cha < TRIE_CHILDREN_COUNT) && (NULL == current->children[cha]))