-2

我正在将字典 Trie 编码为分配 C++ 。在单词中插入某些字母时,我不断收到错误消息,尤其是“l”和“t”,如果它们不是第一个字母。

这是错误

A4Tries.exe 中 0x00EC5392 处的未处理异常:0xC0000005:访问冲突读取位置 0x000032EC。

问题是 InsertTrie 函数。它在以下行中断

if (!current->branch[newkey[i] - 'a'])

我很困惑,因为代码适用于大量测试词,然后输入像'sdfl'或'sfd','ffdf'会破坏程序。如果有人能发现问题,我将不胜感激。谢谢。

const int LETTERS = 26;
typedef char Key[MAXLENGTH];
struct Trienode
{
    Trienode *branch[LETTERS];
    EntryType *ref;
};



class TrieType
{
public:
    TrieType();
    ~TrieType();
    TrieType(TrieType &originalTree);
    void operator=(TrieType & originalTree);
    void MakeEmpty();
    void InsertTrie(Key newkey, EntryType *newentry);
    EntryType *  TrieSearch(Key target);
    bool DeleteTrie(Key delkey);
    void PrintTrie();


private:
    Trienode * root;
};

TrieType::TrieType()
{
    root = NULL;

}


TrieType::~TrieType()
{


}
TrieType::TrieType(TrieType &originalTree)
{

}

EntryType * TrieType::TrieSearch(Key target)
{
    int i;
    Trienode * current = root;
    for (i = 0; i < MAXLENGTH && current; i++)
        if (target[i] == '\0')
            break;
        else
            current =
            current->branch[target[i] - 'a'];
    if (!current)
        return NULL;
    else
        if (!current->ref)
            return NULL;

    return current->ref;
}


Trienode *CreateNode()
{
    int ch;
    Trienode *newnode = new Trienode;
    for (ch = 0; ch < LETTERS; ch++)
        newnode->branch[ch] = NULL;

    newnode->ref = NULL;

    return newnode;
}

void TrieType::InsertTrie(Key newkey, EntryType *newentry)
{
    int i;
    Trienode *current;
    if (!root)
        root = CreateNode();
    current = root;
    for (i = 0; i < MAXLENGTH; i++)
        if (newkey[i] == '\0')
            break;
        else
        {
            if (!current->branch[newkey[i] - 'a'])
                current->branch[newkey[i] - 'a'] = CreateNode();
            current = current->branch[newkey[i] - 'a'];
        }
    if (current->ref != NULL)
        cout << "\nTried to insert a duplicate key." << endl;
    else
        current->ref = newentry;

}



    const int MAXLENGTH = 10;
class EntryType
{
public:
    EntryType();
    EntryType(char * key);
    EntryType(EntryType & entry);
    ~EntryType();
    bool operator== (const EntryType& item) const;
    bool operator!= (const EntryType& item) const;
    void EntryKey(char word[]);
    void PrintWord();

private:
    char entryKey[MAXLENGTH];
};


EntryType::EntryType()
{

}
EntryType::~EntryType()
{

}

void EntryType::EntryKey(char word[])
{
    for (int i = 0; i < 10; i++)
    {
        entryKey[i] = word[i];
    }
}

void EntryType::PrintWord()
{
    cout << entryKey << endl;
}

在主要

void insert(TrieType & trie)
{
    Key word;
    cout << "Please enter the word you would like to enter: " << endl;
    cin >> word;

    EntryType* newEntry = new EntryType;
    newEntry->EntryKey(word);


    trie.InsertTrie(word, newEntry);


}
4

1 回答 1

0

这就是为什么专业程序员使用asserts

    {
        if (!current->branch[newkey[i] - 'a'])
            current->branch[newkey[i] - 'a'] = CreateNode();
        current = current->branch[newkey[i] - 'a'];
    }

newkey[i]不是小写字母时,上面的代码设置current等于垃圾,那么下一次通过循环使用current和seg错误。

代码的其他部分应该负责确保您到达这里时只有小写字母。但由于这对调试这部分代码的人来说并不明显,所以应该有一个断言。

    {
        assert( newkey[i]>='a' && newkey[i]<='z' );
        if (!current->branch[newkey[i] - 'a'])
            current->branch[newkey[i] - 'a'] = CreateNode();
        current = current->branch[newkey[i] - 'a'];
    }

然后,您可以运行程序的调试版本,或者找出失败是由其他地方的代码引起的,该代码允许小写字母以外的字符到达这里,或者您可以看到这不是问题并更好地专注于查找一些不太可能的缺陷。

于 2015-12-31T18:09:31.257 回答