【问题标题】:Data Structure - Trie C++, issue inserting words. Access violation reading location数据结构 - Trie C++,插入单词。访问冲突读取位置
【发布时间】:2015-12-31 16:43:39
【问题描述】:

我正在将字典 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);


}

【问题讨论】:

  • 你真的必须发布一个完整的例子。
  • 失败的代码似乎假定newkey[i] 是一个小写字母。因此,我搜索了您发布的完整代码,以找到任何理由相信或不相信小写字母以外的可能性已被过滤掉。您的代码中应该完成的任何部分甚至都没有包含在您发布的内容中。

标签: c++ data-structures trie search-tree


【解决方案1】:

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

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

当newkey[i]不是小写字母时,上面的代码设置current等于垃圾,然后下一次循环使用current和seg faults。

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

    {
        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'];
    }

然后您可以运行程序的调试版本并找出故障是由允许小写字母以外的字符到达此处的其他代码引起的,或者您可以看到这不是问题并更好地集中注意力发现一些不太可能的缺陷。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多