Trie 实现运行时错误

Trie implementation runtime error

我正在尝试用 C++ 实现 Trie,但出现运行时错误...

这是我的代码:

#include <bits/stdc++.h>
using namespace std;

struct trie{
    bool word = false;
    trie* adj [26];
    trie(){}

    void add(char* s){
        trie* t = this;

        while(s){
            if(t->adj[s[0] - 'a'] == NULL){
                trie nova = create(s);
                t->adj[s[0] - 'a'] = &nova;
                return;
            }
            else{
                t = t->adj[s[0] - 'a'];
            }
            s++;
        }
    }

    trie create(char* s){
        trie t;
        trie* point = &t;
        while(s){
            point->adj[s[0] - 'a'] = new trie();
            point = point->adj[s[0] - 'a'];
            s++;
        }
        point->word = true;
        return t;
    }

    void seek(){
        trie* t = this;
        run(t, "");
    }

    void run(trie* t, string s){
        if(t->word){
            cout<<s<<"\n";
        }
        for(int i = 0; i < 26; i++){
            if(t->adj[i] != NULL){
                run(t->adj[i], s + char('a' + i));
            }
        }
    }
};

int main(){
    trie t;
    t.add("ball");
    t.add("balloon");
    t.add("cluster");
    t.seek();
}

它是这样工作的:

我做错了什么?我是 新手 使用指针,我想我一定是错误地使用了其中一个(或多个)...有什么问题吗?

在您的代码中发现了几个问题。

  1. 一个问题在于堆栈局部变量 trie nova 在超出范围时被删除。

代码

...
if(t->adj[s[0] - 'a'] == NULL){
    trie nova = create(s);
    t->adj[s[0] - 'a'] = &nova; // address points to memory on stack
    return;
} // nova is deleted. t->adj[s[0] - 'a'] is pointing to trash now.
...

要处理它,您应该使用指针和 new 运算符。

...
if(t->adj[s[0] - 'a'] == NULL){
    trie* novaPtr = create(s + 1);
    t->adj[s[0] - 'a'] = novaPtr; 
    return;
} 
...

trie* create(char* s){
    trie *t = new trie();
    trie* point = t;
    while(*s){
        point->adj[s[0] - 'a'] = new trie(); // allocate memory on heap
        point = point->adj[s[0] - 'a'];
        s++;
    }
    point->word = true;
    return t; // the pointer on heap memeroy is returned.
}

  1. 正如@bkVnet 所注意到的,您还应该检查整个地方的 while 循环中的字符串终止。 while(*s) - 意思是 s 没有指向 '[=17=]' 符号而不是 while(s).

  1. 您应该在结构构造函数中使用 NULL 初始化您的 adj 指针。那么在 if(t->adj[s[0] - 'a'] == NULL).
  2. 行中检查它们是否为 NULL 是正确的

构建代码。

trie() {
    for (int i = 0; i < 26; i++) adj[i] = NULL;
}

  1. create(s); 行存在逻辑错误,应删除一个字符 - create(s + 1).

Full working code example