Структура данных - Trie C++, проблема вставки слов. Место чтения нарушения доступа

Я пишу словарь Trie как набор, C++ . Я продолжаю получать ошибку при вставке определенных букв в слова, особенно "l" и "t", если они не являются первыми буквами.

Это ошибка

Необработанное исключение в 0x00EC5392 в A4Tries.exe: 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);


}

1 ответ

Вот почему профессиональные программисты используют asserts

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

когда newkey[i] не строчная буква, вышеуказанные кодовые наборы current равно мусору, то в следующий раз через цикл использует current и сег ошибки.

Другая часть кода должна быть ответственна за то, чтобы к тому времени, когда вы сюда попали, у вас были только строчные буквы. Но поскольку это не очевидно для любого, кто отлаживает эту часть кода, должно быть утверждение.

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

Затем вы можете запустить отладочную сборку программы и либо узнать, что причиной ошибки был этот код в другом месте, что позволило использовать здесь символы, отличные от строчных букв, либо вы можете увидеть, что это не проблема, и лучше сосредоточиться на поиске некоторых менее вероятный дефект.

Другие вопросы по тегам