Pergunta

I have a class that implements a Trie, created using the RAII spirit, and there is a way of using it that leaks memory, I don't understand why.

Class code:

 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();
    };

Now if I do this:

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;

I don't have leaks but if I do this:

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;

I have some leaks. (The leaks are not because of the assignment operator or the constructor because I was using "assert(0)" on the code and it was not being called. I removed the asserts to compile with gcc online.

I'm using Visual Studio but I that same thing is happening when I compile online with http://www.compileonline.com/compile_cpp_online.php

Full code:

http://pastebin.com/qrd7pzMN (leaking) http://pastebin.com/krVFBzmA

The reason why I'm trying it two ways is because I'm trying to experiment a bit with C++ and while I understand that the non leaking way is the less bloated after compiling, I don't like the syntax of using it.

Foi útil?

Solução

You need to have a virtual destructor.

If it's not virtual, the base class (or derived) class destructor won't be called correctly.

The destructor will be hidden, not overridden if it's not virtual.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top