valgrind标识的内存分配错误

时间:2017-12-19 04:18:55

标签: c malloc nodes valgrind trie

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测试返回&#34;无效的大小为8的读数。&#34;我希望下面提供的代码足以说明我在哪里侮辱系统的内存。

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;
}

1 个答案:

答案 0 :(得分:1)

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]))