Trie双自由或析构函数中的损坏 我在C++中编写前缀树类。树中的每个节点都有一个长度为27的数组节点*。这些是用来存放字母和空格的。我通过将所有字母转换为小写,将所有符号转换为空格来清理树中的任何输入。在析构函数中,我调用一个名为clear的函数,该函数接受一个节点(首先是根节点)。编写单元测试时,它只成功地通过一个测试,而调用前缀类上的析构函数的第二个测试失败,并出现双重释放或损坏错误。我以前遇到过这种情况,能够检测到问题并进行补救,但我无法找出原因,以下是一些代码: 节点结构: 插入(公共和私人): 析构函数: 清楚:

Trie双自由或析构函数中的损坏 我在C++中编写前缀树类。树中的每个节点都有一个长度为27的数组节点*。这些是用来存放字母和空格的。我通过将所有字母转换为小写,将所有符号转换为空格来清理树中的任何输入。在析构函数中,我调用一个名为clear的函数,该函数接受一个节点(首先是根节点)。编写单元测试时,它只成功地通过一个测试,而调用前缀类上的析构函数的第二个测试失败,并出现双重释放或损坏错误。我以前遇到过这种情况,能够检测到问题并进行补救,但我无法找出原因,以下是一些代码: 节点结构: 插入(公共和私人): 析构函数: 清楚:,c++,oop,data-structures,destructor,prefix,C++,Oop,Data Structures,Destructor,Prefix,当我注释掉调用clear函数的析构函数中的代码时,它都可以工作(当然有大量内存错误),但当析构函数处于活动状态时,它无法通过2次完整的单元测试来运行它的功能。这可能是一种并非所有变量都被初始化的情况,这会导致对删除的虚假调用。确保节点结构的每个链接在使用前都设置为nullptr 另外,它在虚拟机中运行您的程序来检查常见的内存问题,这对这类事情非常有用。我很困惑,如果我创建了一个新的前缀指针,但不删除它,这将如何改变析构函数的功能?而且我不相信根指针在堆栈上,因为在insert中,我正在检查根元素

当我注释掉调用clear函数的析构函数中的代码时,它都可以工作(当然有大量内存错误),但当析构函数处于活动状态时,它无法通过2次完整的单元测试来运行它的功能。

这可能是一种并非所有变量都被初始化的情况,这会导致对
删除的虚假调用。确保
节点
结构的每个链接在使用前都设置为
nullptr


另外,它在虚拟机中运行您的程序来检查常见的内存问题,这对这类事情非常有用。

我很困惑,如果我创建了一个新的前缀指针,但不删除它,这将如何改变析构函数的功能?而且我不相信根指针在堆栈上,因为在
insert
中,我正在检查根元素是否存在,如果不存在,我将使用
new
分配一个新的根元素,您是否在
前缀的构造函数中将根元素设置为
nullptr
?是,我把它设置为空是因为对于这个任务,自动分级机不包括
-std=c++0x
nullptr
的支持,但是我把它设置为
NULL
很好,我刚刚做了
节点链接[B_因子]={NULL}
,非常感谢。我假设数组中的值有非常疯狂的值,但从技术上讲不是
NULL
,所以clear不知道何时停止,它可能是seg fault或double free。谢谢
const unsigned int B_FACTOR = 27;  // a..z plus space

struct Node_t {
    bool word;
    Node_t *links[B_FACTOR];
    Node_t(): word(false) {}
};
bool Prefix::insert(string thing) {
    sanitize(thing);
    if(!root) root = new Node_t();
    if(thing == "") return true;
    insertPrivate(thing, root);
    return true;
}

void Prefix::insertPrivate(string input, Node_t *node) {
    if(input == "") {
        node->word = true;
        return;
    }
    int idx = (int(input[0])-97) >= 0 ? (int(input[0])-97) : 26;
    if(!node->links[idx]) node->links[idx] = new Node_t();
    insertPrivate(input.substr(1, input.length()), node->links[idx]);
}
Prefix::~Prefix() {
    clear(root);
}
void Prefix::clear(Node_t *node) {
    if(!node) return;
    cout << "On Node " << endl;
    for (int i = 0; i < 26; ++i) {
        clear(node->links[i]);
    }
    delete node;
}
void testInsert0() {
    cout << "testInsert0" << endl;
    Prefix a;
    a.insert("a");
    TS_ASSERT(a.isStored("a"));
}

void testInsert1() {
    cout << "testInsert1" << endl;
    Prefix b;
    b.insert("dd");
    TS_ASSERT_EQUALS(b.isStored("d"), false);
}

void testInsert2() {
    cout << "testInsert2" << endl;
    Prefix a;
    a.insert("abcdef");
    TS_ASSERT(!a.isStored("abcd"));
}
Running cxxtest tests (4 tests).testInsert0
On Node 
On Node 
.testInsert1
Post test
On Node 
On Node 
On Node 
On Node 
On Node 
*** Error in `./testrunner': double free or corruption (out): 0x00000000019652a0 ***
make: *** [test] Aborted (core dumped)