Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这个Geeksforgeks trie实现是否存在内存泄漏问题?_C++_Memory Management_Memory Leaks_Trie - Fatal编程技术网

C++ 这个Geeksforgeks trie实现是否存在内存泄漏问题?

C++ 这个Geeksforgeks trie实现是否存在内存泄漏问题?,c++,memory-management,memory-leaks,trie,C++,Memory Management,Memory Leaks,Trie,我正在读一篇文章,我发现new创建的三节点对象是未删除的,在main函数中,有一个未删除的指针根: 在函数getNode中还有未删除的指针pNode,是否存在内存泄漏?是否应该有一个函数负责破坏由指针组成的trie树 struct TrieNode *getNode(void) { struct TrieNode *pNode = new TrieNode; pNode->isEndOfWord = false; for (int i = 0; i

我正在读一篇文章,我发现new创建的三节点对象是未删除的,在main函数中,有一个未删除的指针根:

在函数getNode中还有未删除的指针pNode,是否存在内存泄漏?是否应该有一个函数负责破坏由指针组成的trie树

struct TrieNode *getNode(void) 
{ 
    struct TrieNode *pNode =  new TrieNode; 
    pNode->isEndOfWord = false; 
  
    for (int i = 0; i < ALPHABET_SIZE; i++) 
        pNode->children[i] = NULL; 
  
    return pNode; 
} 

此函数表示一个契约,其中函数的调用方负责删除分配的三节点。如果调用方不遵守此合同,则只会发生内存泄漏

既然你说这三个代码没有被删除,那么很可能是有漏洞的。除非你能找到这个结构被删除的地方,否则就有漏洞了。这就是为什么RAII是一个如此强大的概念。如果有一个包含所有三节点并负责节点分配和删除的Trie对象,那么您根本不必担心泄漏

让调用者负责管理分配的资源是危险的。不要这样做


您可以争辩说,如果程序足够简单,它所做的只是获取三节点,使用它们做一些事情,然后退出,那么这个特定的实现不一定是泄漏。在这种情况下,内存将在程序退出时释放到操作系统。但这是一个语义参数,提供这样做的示例代码是不好的做法,可能会导致cargo cult程序员这样做。

此函数意味着函数调用方负责删除分配的三节点的契约。如果调用方不遵守此合同,则只会发生内存泄漏

既然你说这三个代码没有被删除,那么很可能是有漏洞的。除非你能找到这个结构被删除的地方,否则就有漏洞了。这就是为什么RAII是一个如此强大的概念。如果有一个包含所有三节点并负责节点分配和删除的Trie对象,那么您根本不必担心泄漏

让调用者负责管理分配的资源是危险的。不要这样做

您可以争辩说,如果程序足够简单,它所做的只是获取三节点,使用它们做一些事情,然后退出,那么这个特定的实现不一定是泄漏。在这种情况下,内存将在程序退出时释放到操作系统。但这是一个语义论点,提供这样做的示例代码是一种不好的做法,可能会导致cargo cult程序员进行这种不好的做法。

泄漏还是不泄漏。。。 根据,当计算机程序以不释放不再需要的内存的方式错误地管理内存分配时,就会发生泄漏:

getNode的作用是返回指向已初始化三节点的指针。因此它本身不会泄漏任何东西:我们可以假设,根据它的用途,当函数返回其指针时,仍然需要相应的对象

调用上下文确实会泄漏内存:正如您正确指出的,它使用getNode创建一个节点,并且从不删除该节点。这是个坏习惯

但您必须在上下文中替换此代码:本文是一篇教程。它建议将删除作为一项补充

为什么不在教程中显示删除 因为删除三节点并不是一件容易的事情,如果你必须自己小心的话:删除一个节点还需要找到所有应该删除的引用节点。由于trie是一个图,因此多个节点可以指向同一个目标。因此,如果您不想因为悬空指针和双重删除而冒UB风险,就不能盲目删除这些节点。您需要实现标记算法或某种引用计数

但不要遵循本教程 这种三节点实现非常糟糕:在现代C++中:

您应该让构造函数初始化一个三节点,无论它是动态创建的节点还是本地节点。 您应该使用智能指针而不是原始指针。由于一个节点本质上可以被引用多次,所以您需要一个共享的\u ptr 您可能更喜欢使用向量甚至贴图,而不是旧式数组。 但我还是让你把删除作为练习-

泄漏还是不泄漏。。。 根据,当计算机程序以不释放不再需要的内存的方式错误地管理内存分配时,就会发生泄漏:

getNode的作用是返回指向已初始化三节点的指针。因此它本身不会泄漏任何东西:我们可以假设,根据它的用途,当函数返回其指针时,仍然需要相应的对象

调用上下文确实会泄漏内存:正如您正确指出的,它使用getNode创建一个节点,并且从不删除该节点。这是个坏习惯

但您必须在上下文中替换此代码:文章 这是一个教程。它建议将删除作为一项补充

为什么不在教程中显示删除 因为删除三节点并不是一件容易的事情,如果你必须自己小心的话:删除一个节点还需要找到所有应该删除的引用节点。由于trie是一个图,因此多个节点可以指向同一个目标。因此,如果您不想因为悬空指针和双重删除而冒UB风险,就不能盲目删除这些节点。您需要实现标记算法或某种引用计数

但不要遵循本教程 这种三节点实现非常糟糕:在现代C++中:

您应该让构造函数初始化一个三节点,无论它是动态创建的节点还是本地节点。 您应该使用智能指针而不是原始指针。由于一个节点本质上可以被引用多次,所以您需要一个共享的\u ptr 您可能更喜欢使用向量甚至贴图,而不是旧式数组。
但我还是让你把删除作为练习-

如果返回的是std::unique_ptr而不是原始指针,那么毫无疑问……那个极客网站上的代码非常糟糕。很少有一个实际的代码示例没有被bug困扰。所以,是的,它泄漏内存。StultTeNoNODE应该是一个符号,写代码的人不知道C++或者是懒惰,因为使用了C++的大部分C实现,如果返回STD::UnQuyJPtR而不是原始指针,那么毫无疑问……GeEK网站上的代码非常差。很少有一个实际的代码示例没有被bug困扰。所以,它泄漏内存。StultTeNoNODE应该是一个符号,写代码的人不知道C++或是懒惰,主要是使用C++实现C。
struct TrieNode *getNode(void) 
{ 
    struct TrieNode *pNode =  new TrieNode; 
    pNode->isEndOfWord = false; 
  
    for (int i = 0; i < ALPHABET_SIZE; i++) 
        pNode->children[i] = NULL; 
  
    return pNode; 
}