Trie in C:指针检测为null。导致内存泄漏

时间:2014-03-28 20:30:58

标签: c pointers memory-leaks trie

我从哈佛大学(CS 50)学习在线计算机科学MOOC,对于其中一个问题集,你必须将字典加载到某种数据结构中(我选择了一个Trie)和然后使用所述数据结构来检查信息。我正在编写加载字典的功能,并且我已经了解了一些重大问题。尽管尝试检测NULL指针,但我仍在继续分配内存。

这是我的代码:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"
#include <ctype.h>
//Defines the trie data structure which is used to store the words
struct trieNode{
    char letter;
    bool wordComp;
    bool isRoot;
    struct trieNode* childNodes[27];
 }trie;
 //The trie that will be used for the rest of the program
 struct trieNode root;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
    // TODO
    return false;
}

/**
 * Loads dictionary into memory.  Returns true if successful else false.
 */
bool load(const char* dictionary)
{
    //Counts to see whether the word was just an \n or it was really a word
    int cLettCount = 0;
    //counts the number of total words used
    int tWordCount = 0;
    //basic setup stuff
    root.isRoot = true;
    //Pointer to the current node (current node starts as root node).
    struct trieNode* currNode = &root;
    FILE* dic = fopen(dictionary, "r");
    char currChar = 1;
    //main loop (Goes till end of file)
    while(currChar != EOF){
        //resets letter count
        cLettCount = 0;
        //resets currNode to the root node
        currNode = &root;
        currChar = 1;
        //Loop gathers current word and pushes the letters to the trie
        for(int j = 0;  currChar != '\n'; j++){
            currChar = fgetc(dic);
            //Makes sure we're not at the end of a word or at EOF
            if(currChar == '\n'|| currChar == EOF)
            {
                break;
            }
            //Makes sure we only get alpha chars
            else if(!isalpha(currChar) && currChar != 39)
            {
                printf("Nonalpha char %c detected. Quiting...\n", currChar);
                return false;
            }
            //Meat and bones. Adds letters onto the trie
            else
            {
                bool isNull = false;
                if(currChar == 39){
                    currNode = currNode->childNodes[26];
                    if(currNode->childNodes[26] == NULL)
                    {
                        isNull = true;
                    }
                }
                else
                {
                //Finds the node that corrosponds with the letter
                    if(currNode->childNodes[currChar - 97] == NULL)
                    {
                        isNull = true;
                    }
                    currNode = currNode->childNodes[currChar - 97];
                }
                if(isNull)
                {
                     currNode = malloc (sizeof (trie));
                     currNode->isRoot = false;
                     currNode->letter = currChar;
                     currNode-> wordComp = false;
                     printf("Node created for: %c\n", currNode->letter);
                }else if(!isNull){
                    printf("Node not created\n");
                }
            }
        }
        if(currChar == EOF){
                break;
        }
        else if(currChar == '\n'){
            currNode -> wordComp = true;
            tWordCount++;
            printf("\n");
        }
    }
    return true;
}

/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
unsigned int size(void)
{
    // TODO
    return 0;
}

/**
 * Unloads dictionary from memory.  Returns true if successful else false.
 */
bool unload(void)
{
    // TODO
    return false;
}

Load()是我的问题所在。

2 个答案:

答案 0 :(得分:1)

你打败了我,我需要学会更快地打字:)

首先,一些挑剔:

不要将硬代码用于字符常量

 39 should be '\''
 97 should be 'a'

请注意,大写字母会使程序崩溃。在将外部输入转换为数组索引后,始终进行范围检查,例如

index = currChar - 'a';
if ( index < 0 || index > 25 )
   return false;

现在为肉:

代码在检测到NULL节点时会创建一个新节点。但是,它不会将指针存储到父节点中的新节点。因此,父节点中的指针将始终为NULL。

答案 1 :(得分:0)

我想我只知道自己的错误。我正在将curNode设置为新节点,而不是根节点中的指针。