-6

I'm implementing a trie class, and following the rule of three in C++: has both nondefault coppy constructor, assignment operator and the destructor. However the program still crashes. What's wrong with the code?

class Trie
{
private:
    char ch;
    std::vector<Trie*> children;

public:
    std::string* word;
    static std::size_t nodeCount;
    Trie()
    {
        ch=0;
        word=NULL;
        ++nodeCount;
    };

    Trie(char c)
    {
        ch=c;
        word=NULL;
        ++nodeCount;
    };

    ~Trie()
    {
        cleanup();
        --nodeCount;
    };

    Trie(const Trie& source)
    {
        std::cout<<"hello world!\n";
        ch=source.ch;       
        if (source.word)
            word = new std::string(*(source.word));
        for (int i=0; i<int(source.children.size()); i++)
        {
            Trie* newA=new Trie(*(source.children[i]));
            children.push_back(newA);
        }
    }

    Trie& operator=(const Trie &source)
    {
        cleanup();
        ch=source.ch;       
        if (source.word)
            word = new std::string(*(source.word));
        for (int i=0; i<int(source.children.size()); i++)
        {
            Trie* newA=new Trie(*(source.children[i]));
            children.push_back(newA);
        }
        return *this;
    }
    void cleanup()
    {
        for (int i=0; i<int(children.size()); i++)
        {
            delete children[i];
        }
        if (word)
            delete word;
    }

P/S: This is the test function for deconstructor and the code pass the test:

TEST(memory)
{
  std::size_t base = Trie::nodeCount;
  // many nodes in the global Boggle trie
  CHECK( base == 0 );
  Trie *trie = new Trie();
  CHECK_EQUAL( base + 1, Trie::nodeCount );
  trie->addWord( "and" );
  CHECK_EQUAL( base + 4, Trie::nodeCount );
  trie->addWord( "ant" );
  CHECK_EQUAL( base + 5, Trie::nodeCount );
  delete trie;
  CHECK_EQUAL( base, Trie::nodeCount );
}

However the code failed the copy constructor and assignment test:

TEST(copyTrie)
{
  Trie trie;
  trie.addWord( "and" );
  trie.addWord( "ant" );
  CHECK_EQUAL( "and", *(trie.next('a')->next('n')->next('d')->word) );
  CHECK_EQUAL( "ant", *(trie.next('a')->next('n')->next('t')->word) );

  Trie copy( trie );
  CHECK_EQUAL( "and", *(copy.next('a')->next('n')->next('d')->word) );
  CHECK_EQUAL( "ant", *(copy.next('a')->next('n')->next('t')->word) );

  copy.addWord( "bee" );
  trie.addWord( "cat" );
}

It crashed exactly at the last command trie.addWord("cat")

Dzung Nguyen
  • 3,794
  • 9
  • 48
  • 86

1 Answers1

2

Your cleanup function doesn't empty the children vector.

JoeG
  • 12,994
  • 1
  • 38
  • 63
  • 1
    Then what is `cleanup` doing? – David G Dec 20 '13 at 00:02
  • 1
    I'm really not sure, but I had a loop that delete everything in children vector. Is that the correct way? – Dzung Nguyen Dec 20 '13 at 00:04
  • 3
    @0x499602D2: No, it isn't. Dzung Nguyen: You are deleting the pointed at objects but not removing the pointers. – JoeG Dec 20 '13 at 00:06
  • 4
    @JoeGauterin Your answer can easily be misinterpreted (although you're correct). You could emphasize the difference between deleting elements and clearing the container itself, also why it's crucial in this case to do the latter. – leemes Dec 20 '13 at 00:08