2017-08-18 10 views
-1

このコードは、C++ 14の単純なTrie実装です。 add("name")機能次のエラーを実行するときのポップ・アップ:EXC_BAD_ACCESS(コード= 1、アドレス= 0x20に))unordered_mapのEXC_BAD_ACCESS

は、いくつかのデバッグイメージの下に従う:

enter image description here

enter image description here

は、以下のコードの後に​​続きます:

struct TrieNode { 
    string value; 
    unordered_map<char, TrieNode *> children = {}; 
}; 

class Trie { 
public: 
    TrieNode *root = new TrieNode; 

    TrieNode *find(string query); 

    int countPartialFind(string query); 

    void add(string value); 

private: 
    void add(string value, TrieNode *node); 

    TrieNode *createNewNode(string &value, int counter, unordered_map<char, TrieNode *> &children); 

    void add(string value, int counter, TrieNode *node); 

    TrieNode *findNode(char query, unordered_map<char, TrieNode *> &children); 
}; 

TrieNode *Trie::find(string value) { 
    TrieNode *tmpNode = root; 
    for (int counter = 0; counter < value.length(); counter++) { 
    tmpNode = findNode(value[counter], tmpNode->children); 
    if (tmpNode == NULL) { 
     return NULL; 
    } 
    } 

    return tmpNode; 
} 

int Trie::countPartialFind(string query) { 
    TrieNode *matchNode = find(query); 
    if (matchNode == NULL) { 
    return 0; 
    } 

    return matchNode->children.size(); 
} 

void Trie::add(string value, int counter, TrieNode *node) { 
    for (; counter < value.length(); counter++) { 
    node = findNode(value[counter], node->children); 
    if (node == NULL) { 
     node = createNewNode(value, counter, node->children);; 
    } 
    } 
} 

TrieNode *Trie::findNode(char query, unordered_map<char, TrieNode *> &children) { 
    unordered_map<char, TrieNode *>::const_iterator search = children.find(query); 
    if (search == children.end()) { 
    return NULL; 
    } 
    return search->second; 
} 

TrieNode *Trie::createNewNode(string &value, int counter, unordered_map<char, TrieNode *> &children) { 
    TrieNode *newNode = new TrieNode; 
    newNode->value = value.substr(0, counter + 1); 
    char tmp = value[counter]; 
    children[tmp] = newNode; 
    return newNode; 
} 

void Trie::add(string value) { 
    if (value.length() == 0) { return; } 
    int counter = 0; 

    TrieNode *tmpNode = findNode(value[counter], root->children); 

    if (tmpNode == NULL) { 
    tmpNode = createNewNode(value, counter, root->children); 
    } 

    add(value, ++counter, tmpNode); 
} 

問題は簡単ですが、私はそれをキャッチできません。助けてくれてありがとう、私に教えてくださいできる他の最適化やコードデザインがあります。

+2

デバッガでコードをステップ実行して、実際に例外をトリガする行を見つけましたか? – NathanOliver

+0

はい、それをキャッチしませんでした。申し訳ありませんが、そのエラーはとても愚かであり、私は恥ずかしいでしょう。 –

答えて

2

3つのパラメータTrie::addでは、createNewNodeを呼び出すと、nodeNULLとなります。 3番目のパラメータnode->childrenは、NULLポインタをデリファレンスして、未定義の動作(この場合はクラッシュ)を発生させます。

ローカル変数の値でコールスタックを検索すると、これを見ることができます。

+0

ありがとう、問題は本当に愚かだった、もう一度ありがとう。 –