-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してセグ フォールトを使用します。

コードの他の部分は、ここに到達するまでに小文字のみを使用するようにする責任があります。しかし、それはコードのこの部分をデバッグする人には明らかではないため、アサートが必要です。

    {
        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 に答える