Search code examples
c++templatesnew-operatorallocation

Tree class with template and dynamic allocation for children


So I am writing a Node template class with n children. My problem is in the constructor. It seems that when I want to allocate memory for an array of Node type (in Node(V data) constructor), the memory is not allocated even though I use new.


As you can see in this image of memory state, there is nothing on the heap. Memory state

Here is my code.

template <typename V>
class Node {
private:
  V _data;
  unsigned short _size;
  Node<V>* _children;
public:
  Node();
  Node(V, unsigned short);
  Node(const Node&); // copy constructor
  Node& operator= (Node&); // assignement by copy constructor
  Node (Node&&); // transfer constructor
  Node& operator= (Node&&); // assignement by transfer constructor
  ~Node();
};

template <typename V>
Node<V>::Node()
  : _data(0), _size(0), _children(nullptr) {}

template <typename V>
Node<V>::Node(V data, unsigned short size)
  : _data(data), _size(size), _children(new Node<V>[_size]) {}

template <typename V>
Node<V>::Node (const Node& other)
  : _size(other._size), _data(other._data) {
  _children = new Node<V>[_size];
  for (unsigned short i = 0; i < _size; i++) 
    _children[i] = other._children[i];
}

template <typename V>
Node<V>& Node<V>::operator= (Node& n){
  if (&n != this) {
    delete[] _children;
    _data = n._data; _children = n._children; _size = n._size;
    n._data = 0; n._size = 0; n._children = nullptr;
  }
  return *this;
}

template <typename V>
Node<V>::Node (Node&& n){
  _data = n._data; _size = n._size; _children = n._children;
  n._data = 0; n._size = 0; n._children = nullptr;
}

template <typename V>
Node<V>& Node<V>::operator= (Node&& n){
  if (&n != this) {
    delete[] _children;
    _data = n._data; _children = n._children; _size = n._size;
    n._data = 0; n._size = 0; n._children = nullptr;
  }
  return *this; 
}

template <typename V>
Node<V>::~Node() { delete[] _children; }



int main() {
  Node<char> n1('A',5);
  return 0;
}

Thank you in advence


Solution

  • (Sorry for posting as an answer, but there's a character limit in the comments)

    This is what I see when I actually step through a debugger. It runs like you expect, assigning _children a pointer, and then initializing the 5 Node objects in that space. Based on this, I believe the visualization tool you were using has a bug.

    Temporary breakpoint 1, main () at ex.cpp:64
    64      int main() {
    (gdb) step
    65                Node<char> n1('A',5);
    (gdb) step
    Node<char>::Node (this=0x7ffffffedc90, data=65 'A', size=5) at ex.cpp:22
    22                Node<V>::Node(V data, unsigned short size)
    (gdb) step
    23                : _data(data), _size(size), _children(new Node<V>[_size]) {}
    (gdb) p data
    $1 = 65 'A'
    (gdb) p size
    $2 = 5
    (gdb) step
    Node<char>::Node (this=0x8413e78) at ex.cpp:19
    19                : _data(0), _size(0), _children(nullptr) {}
    (gdb) step
    Node<char>::Node (this=0x8413e88) at ex.cpp:19
    19                : _data(0), _size(0), _children(nullptr) {}
    (gdb) step
    Node<char>::Node (this=0x8413e98) at ex.cpp:19
    19                : _data(0), _size(0), _children(nullptr) {}
    (gdb) step
    Node<char>::Node (this=0x8413ea8) at ex.cpp:19
    19                : _data(0), _size(0), _children(nullptr) {}
    (gdb) step
    Node<char>::Node (this=0x8413eb8) at ex.cpp:19
    19                : _data(0), _size(0), _children(nullptr) {}
    (gdb) step
    Node<char>::~Node (this=0x7ffffffedc90, __in_chrg=<optimized out>) at ex.cpp:60
    60      Node<V>::~Node() { delete[] _children; }
    (gdb) p _children
    $3 = (Node<char> *) 0x8413e78
    (gdb) step
    Node<char>::~Node (this=0x8413eb8, __in_chrg=<optimized out>) at ex.cpp:60
    60      Node<V>::~Node() { delete[] _children; }
    (gdb) step
    0x00007fffff1013c0 in operator delete[](void*, unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    (gdb) step
    Single stepping until exit from function _ZdaPvm,