【问题标题】:Trie unsuccessful deletion尝试删除不成功
【发布时间】:2015-01-28 04:38:18
【问题描述】:

我有一个用 C++ 编写的 Trie 程序。删除 Trie 存在问题。即使代码正在执行删除操作,内存也不会被释放。有人可以指出我做错了什么吗?程序不处理从 Trie 中删除单个字符串。下面是删除sn-p的代码。

void deleteTrie(trieNodeT **t) {
    if(*t) {
        trieNodeT *current = *t;
        for(int i=0; i<26; i++) {
            if(current->children[i]) {
                deleteTrie(&current->children[i]);
                free (current->children[i]);
            }
        }
    }
}

void deleteEntireTrie(trieCDT *t) {
    if (t) {
       deleteTrie(&t->root);
    }
} 

下面是完整源代码的链接:
https://ideone.com/xL7bvu

【问题讨论】:

  • 究竟是什么让你相信内存没有被释放?释放的内存不会从机器上物理删除,不会从地址空间中删除,甚至不会立即被覆盖。
  • @ricl,这是真的“释放的内存不会从机器上物理删除”。我尝试使用 gdb,当 'i' 值更改时,我尝试访问 current->children[i] - 'i' - 以前的值。我的钥匙完好无损,而且我一直看到这一点。
  • 是的,你期待什么?

标签: c++ c data-structures


【解决方案1】:

鉴于这是 C++:

(trieNodeT *) malloc(sizeof(trieNodeT));  

应该是:

new trieNodeT;

您不能同时使用deletemalloc,这是未定义的行为。

或者,您可以替换:

delete current->children[i];

free(current->children[i]);

您可能还需要在要删除的内容中写出 null:

if(current->children[i]) {
    deleteTrie(&current->children[i]);
    delete current->children[i];
    current->children[i] = nullptr; // or 0
}

【讨论】:

  • 如果我删除指针,为什么我需要再次将其设置为 NULL。在那种情况下,为什么要删除?特别是在这种情况下。我总是发现指针及其值完好无损。
【解决方案2】:

根节点的删除在哪里?

您无需将指针设为空即可使删除生效。内存被删除语句“标记”删除。如果您不使指针为空,则指针仍指向“标记”的已删除内存区域。 C++ 纯粹主义者会跳起来说我下面所说的是错误的——在删除之后,如果你通过那个旧指针访问内存,在许多实现中,数据仍然存在。因为内存块刚刚被标记为已删除;不被物理覆盖。但是您永远不应该访问已删除的内存。程序带走标记的已删除内存,并在下一次需要内存时将其分配;而且您无法控制它。而使用多线程,这些内存甚至可能“立即”消失。

【讨论】:

    猜你喜欢
    • 2021-01-04
    • 1970-01-01
    • 2018-02-10
    • 2017-03-12
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2017-12-13
    相关资源
    最近更新 更多