2014-01-25 62 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