Reputation:
I have a Tree class which has a nested private Node class. The constructor of my Tree class creates a Node object and set it to _info
which is a pointer to a Node type in my Tree class.
I don't have any errors but when I check my program for memory leaks with valgrind, I see that I have memory leaks.
I know that the problem is with the deconstructor but i don't know how to solve it.
Just before showing the code, I should mention that the second argument of my template (N) is not important here and simply you could ignor it.
Here is my code: tree.hpp
#ifndef TREE_HPP
#define TREE_HPP
#include <iostream>
#include <cstddef>
template <typename T, char N>
class Tree {
private:
class Node;
Node* _info;
public:
Tree();
Tree(T, char);
Tree(const Tree&) = delete;
Tree& operator= (const Tree&) = delete;
Tree (Tree&&);
Tree& operator= (Tree&&);
~Tree() {delete _info;} // something is wrong here
bool ins(char, Tree*);
Tree* fils(char);
void print(){
std::cout << _info->getData() << std::endl;
}
};
template <typename T, char N>
bool Tree<T, N>::ins(char index, Tree* childTree){
if (_info){
_info->getChildren()[index] = childTree;
return true;
}
return false;
}
template <typename T, char N>
Tree<T, N>::Tree()
: _info(nullptr) {}
template <typename T, char N>
Tree<T, N>::Tree(T data, char size) {
Node* node = new Node(data, size); // I think I don't free this
_info = node;
}
template <typename T, char N>
Tree<T, N>::Tree(Tree&& t) {
_info = t._info;
t._info = nullptr;
}
template <typename T, char N>
Tree<T, N>& Tree<T, N>::operator= (Tree&& t) {
if (&t != this) {delete _info; _info = t._info; t._info = nullptr;}
return *this;
}
template <typename T, char N>
typename Tree<T,N>::Node* Tree<T, N>::info() { return _info;}
template <typename T, char N>
Tree<T,N>* Tree<T, N>::fils(char index){
return _info->getChildren()[index];
}
template <typename T, char N>
class Tree<T, N>::Node {
private:
T _data;
Tree* _children;
bool _isWord;
public:
Node();
Node(T, char);
Tree** getChildren() {return &this->_children;}
T getData(){return this->_data;}
~Node() = default;
};
template <typename T, char N>
Tree<T,N>::Node::Node(){
_data = 0;
_children = nullptr;
_isWord = false;
}
template <typename T, char N>
Tree<T,N>::Node::Node(T data, char size){
_data = data;
_isWord = false;
_children = new Tree<T,N>[size];
}
#endif
main.cpp
#include <iostream>
#include <cstddef>
#include <exception>
#include "tree.hpp"
#define SIZE 5
int main() {
Tree<char,SIZE> n1('A',SIZE);
Tree<char,SIZE> n1_1('B',SIZE);
Tree<char,SIZE> n1_2('C',10); // ! here the size is always 5
Tree<char,SIZE> n1_1_1('D',SIZE);
n1.ins(0,&n1_1);
n1.ins(1,&n1_2);
n1_1.ins(0,&n1_1_1);
n1.fils(0)->print();
n1.fils(1)->print();
n1_1.fils(0)->print();
return 0;
}
I am also open to any suggestion to improve my code.
Thank you in advanced
Upvotes: 0
Views: 165
Reputation: 238461
_children = new Tree<T,N>[size];
There is no delete[] _children;
anywhere.
Even more problematic:
Tree** getChildren() {return &this->_children;}
This function returns a pointer to a solitary Tree*
object that is not an element of an array.
return _info->getChildren()[index];
Here, you index into that pointer to a solitary object as if it were in an array. Using any other index than 0 has UB.
Upvotes: 1