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

Ваш код на самом деле действительно очень трудно отслеживать. Мне пришлось сделать «diffchecker.com» на двух сайтах pasteein, чтобы увидеть разницу. Я не уверен, буду ли я называть это «памятью» утечки». Вы просто удаляете свои указатели несколько раз? Ну, вот что ваш код, кажется, печатает. Для этого вам не хватает «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 thanks, я использовал assert (0) в режиме Release, поэтому я думал, что другие конструкторы не были доступны. Затем я сохранил «Создано» в init. Благодаря! – user246100