2014-01-25 31 views
2

我有一个类实现了Trie,使用RAII精神创建,并有一种使用它泄漏内存的方式,我不明白为什么。内存泄漏时扩展类

类代码:

template <typename T,typename C,int Base> 
    struct TrieNode 
    { 
    TrieNode* childs[Base]; 
    T n; 

    unsigned int val; 

    void init(unsigned int val); 
    { 
     Created++; 

     this->val = val; 
     memset(childs, 0 ,sizeof(TrieNode*) * Base); 
     n = create_empty<T>(); 
    } 

    TrieNode(int mult) 
    { 
     init(mult); 
    } 

    ~TrieNode() 
    { 
     Deleted++; 

     for(int i=0;i<Base;i++) 
     delete childs[i]; 
    } 


    T& create(unsigned int number,int mult); 
    C get_keys(int val); 
    TrieNode& move(TrieNode& other); 


    public : 

     TrieNode(){ init(1); } 
     TrieNode (const TrieNode& other) 
     { 
     move(const_cast<TrieNode&>(other)); 
     } 

     TrieNode& operator= (TrieNode other) 
     { 
     return move(other); 
     } 

     T& operator[](unsigned int number) 
     { 
     return this->create(number,1); 
     } 

     bool is_empty(); 
     C get_keys(); 
    }; 

现在,如果我这样做:

template<typename T,typename C> 
struct TrieNodeTen 
{ 
    typedef TrieNode<T,C,10> type; 
}; 

template <typename T> 
struct TrieNodeTenVec 
{ 
    typedef typename TrieNodeTen<T,std::vector<int>>::type type; 
}; 


TrieNodeTenVec< TrieNodeTenVec<bool>::type >::type trie; 

我没有泄露,但如果我这样做:

template <typename T,typename C> 
class TrieNodeTen1 : public TrieNode<T,C,10> {}; 

template <typename T> 
class TrieNodeTenVec1 : public TrieNodeTen1<T,std::vector<int> > {}; 

TrieNodeTenVec1< TrieNodeTenVec1<bool> > trie; 

我有一些泄漏。 (泄漏不是因为赋值操作符或构造函数,因为我在代码中使用了“assert(0)”,并且它没有被调用。我删除了断言,以便在线编译gcc。

我是使用Visual Studio,但我当我在线编译同样的事情也发生 http://www.compileonline.com/compile_cpp_online.php

全码:

http://pastebin.com/qrd7pzMN(泄漏) http://pastebin.com/krVFBzmA

为什么我想这两个方面的原因是因为一世' m试图用C++做一点实验,虽然我知道编译后非渗漏的方式不那么臃肿,但我不喜欢使用它的语法。

+1

你的代码其实真的很难遵循..我必须在两个pastebin链接上做一个“diffchecker.com”才能看出区别..我不确定是否将它称为“内存泄漏”。你只是多次删除你的指针?那么这就是你的代码似乎正在打印出来。你错过了很多,这是“RAII”。移动,复制和分配。 – Brandon

+0

就像Yochai所说的,我并没有增加“创造”时间,我应该这样报道更多的删除创作。对不起,代码难以遵循,我是一个新手。 – user246100

+0

关于RAII部分,我错过了哪些功能?我创建了两个用于构建和分配的功能,将旧类中的数据移动到新类中。 – user246100

回答

1

您需要有一个虚拟析构函数。

如果它不是虚拟的,基类(或派生)类析构函数将不会被正确调用。

析构函数将被隐藏,如果它不是虚拟的,则不会覆盖。

+0

只是让它虚拟?它仍然泄漏: http://pastebin.com/0QUK62BF http://www.compileonline.com/compile_cpp_online.php – user246100

+1

@ user246100你的计数是错误的。在每个构造函数中放一个增量,而不是每个init。而且我希望你已经注意到你的数据删除比建筑更多。这意味着错误的计数,而不是内存泄漏。 –

+0

Omg谢谢,我在释放模式下使用assert(0),所以我在想其他构造函数没有被访问。然后我在init中保存“Created”。谢谢! – user246100