M
mast2as
Hi guys
I wrote a short program to test a Tree class... I plan to use it a lot
in my application so thought I would do a memory leak check before I
start using it. The code seems good to me in a glance (new & delete
seem to be called for all dynamically crated objects) but when I run
valgrind, valgrind reports a memory leak.
The problem seems to come when i start using push().
Could anyone help me with this please ? I just don't see what i am
doing wrong.
thank you, mark
#include <iostream>
#include <deque>
using namespace std;
template<typename T>
class TreeNode
{
public:
TreeNode( ) : m_parent( NULL ) {
cout << "new node" << endl;
//cout << "new data" << endl;
//m_data = new T;
}
~TreeNode() {
cout << "delete node\n";
//cout << "delete data\n";
//delete m_data;
}
void setData( T data ) { m_data = data; }
void setParent( TreeNode<T> *node ) { m_parent = node; }
TreeNode<T> *getParent() const { return m_parent; }
T getData() const { return m_data; }
private:
TreeNode<T> *m_parent;
T m_data;
};
template<typename T>
class Tree
{
public:
Tree() {
m_currentNode = new TreeNode<T>;
m_currentNode->setParent( NULL );
}
~Tree() {
cout << "Tree destructor " << m_nodes.size() << endl;
while ( ! m_nodes.empty() ) {
TreeNode<T> *node = m_nodes.back();
m_nodes.pop_back();
delete node;
}
delete m_currentNode;
}
void push( T data )
{
TreeNode<T> *node = new TreeNode<T>;
cout << "size of Node " << sizeof( *node ) << endl;
node->setParent( m_currentNode );
node->setData( data );
m_nodes.push_back( node );
m_currentNode = node;
}
void pop() {
if ( m_currentNode->getParent() ) {
m_currentNode = m_currentNode->getParent();
} else {
cout << "Tree::data out of range (abort)" << endl;
}
}
T getCurrentData() const { return m_currentNode->getData(); }
int getTreeSize() const { return m_nodes.size(); }
private:
TreeNode<T> *m_currentNode;
deque<TreeNode<T> *> m_nodes;
};
int main()
{
Tree<int> tree;
tree.push( 1 );
return 0;
}
/// running it
new node
new node
size of Node 8
Tree destructor 1
delete node
delete node
/// VALGRIND REPORT
==12771==
new node
new node
size of Node 8
Tree destructor 1
delete node
delete node
==12771== Invalid free() / delete / delete[]
==12771== at 0x1B904616: operator delete(void*)
(vg_replace_malloc.c:156)
==12771== by 0x8048B2B: Tree<int>::~Tree() (in p_proto1/test)
==12771== by 0x80489BD: main (in p_proto1/test)
==12771== Address 0x1BB457C0 is 0 bytes inside a block of size 8
free'd
==12771== at 0x1B904616: operator delete(void*)
(vg_replace_malloc.c:156)
==12771== by 0x8048B05: Tree<int>::~Tree() (in p_proto1/test)
==12771== by 0x80489BD: main (in p_proto1/test)
==12771==
==12771== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from
1)
==12771== malloc/free: in use at exit: 1288 bytes in 2 blocks.
==12771== malloc/free: 4 allocs, 3 frees, 1808 bytes allocated.
==12771== For counts of detected errors, rerun with: -v
==12771== searching for pointers to 2 not-freed blocks.
==12771== checked 2370936 bytes.
==12771==
==12771==
==12771== 8 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12771== at 0x1B90406F: operator new(unsigned)
(vg_replace_malloc.c:133)
==12771== by 0x8048DD0: Tree<int>::Tree() (in p_proto1/test)
==12771== by 0x804899F: main (in p_proto1/test)
==12771==
==12771== LEAK SUMMARY:
==12771== definitely lost: 8 bytes in 1 blocks.
==12771== possibly lost: 0 bytes in 0 blocks.
==12771== still reachable: 1280 bytes in 1 blocks.
==12771== suppressed: 0 bytes in 0 blocks.
==12771== Reachable blocks (those to which a pointer was found) are not
shown.
==12771== To see them, rerun with: --show-reachable=yes
I wrote a short program to test a Tree class... I plan to use it a lot
in my application so thought I would do a memory leak check before I
start using it. The code seems good to me in a glance (new & delete
seem to be called for all dynamically crated objects) but when I run
valgrind, valgrind reports a memory leak.
The problem seems to come when i start using push().
Could anyone help me with this please ? I just don't see what i am
doing wrong.
thank you, mark
#include <iostream>
#include <deque>
using namespace std;
template<typename T>
class TreeNode
{
public:
TreeNode( ) : m_parent( NULL ) {
cout << "new node" << endl;
//cout << "new data" << endl;
//m_data = new T;
}
~TreeNode() {
cout << "delete node\n";
//cout << "delete data\n";
//delete m_data;
}
void setData( T data ) { m_data = data; }
void setParent( TreeNode<T> *node ) { m_parent = node; }
TreeNode<T> *getParent() const { return m_parent; }
T getData() const { return m_data; }
private:
TreeNode<T> *m_parent;
T m_data;
};
template<typename T>
class Tree
{
public:
Tree() {
m_currentNode = new TreeNode<T>;
m_currentNode->setParent( NULL );
}
~Tree() {
cout << "Tree destructor " << m_nodes.size() << endl;
while ( ! m_nodes.empty() ) {
TreeNode<T> *node = m_nodes.back();
m_nodes.pop_back();
delete node;
}
delete m_currentNode;
}
void push( T data )
{
TreeNode<T> *node = new TreeNode<T>;
cout << "size of Node " << sizeof( *node ) << endl;
node->setParent( m_currentNode );
node->setData( data );
m_nodes.push_back( node );
m_currentNode = node;
}
void pop() {
if ( m_currentNode->getParent() ) {
m_currentNode = m_currentNode->getParent();
} else {
cout << "Tree::data out of range (abort)" << endl;
}
}
T getCurrentData() const { return m_currentNode->getData(); }
int getTreeSize() const { return m_nodes.size(); }
private:
TreeNode<T> *m_currentNode;
deque<TreeNode<T> *> m_nodes;
};
int main()
{
Tree<int> tree;
tree.push( 1 );
return 0;
}
/// running it
new node
new node
size of Node 8
Tree destructor 1
delete node
delete node
/// VALGRIND REPORT
==12771==
new node
new node
size of Node 8
Tree destructor 1
delete node
delete node
==12771== Invalid free() / delete / delete[]
==12771== at 0x1B904616: operator delete(void*)
(vg_replace_malloc.c:156)
==12771== by 0x8048B2B: Tree<int>::~Tree() (in p_proto1/test)
==12771== by 0x80489BD: main (in p_proto1/test)
==12771== Address 0x1BB457C0 is 0 bytes inside a block of size 8
free'd
==12771== at 0x1B904616: operator delete(void*)
(vg_replace_malloc.c:156)
==12771== by 0x8048B05: Tree<int>::~Tree() (in p_proto1/test)
==12771== by 0x80489BD: main (in p_proto1/test)
==12771==
==12771== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from
1)
==12771== malloc/free: in use at exit: 1288 bytes in 2 blocks.
==12771== malloc/free: 4 allocs, 3 frees, 1808 bytes allocated.
==12771== For counts of detected errors, rerun with: -v
==12771== searching for pointers to 2 not-freed blocks.
==12771== checked 2370936 bytes.
==12771==
==12771==
==12771== 8 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12771== at 0x1B90406F: operator new(unsigned)
(vg_replace_malloc.c:133)
==12771== by 0x8048DD0: Tree<int>::Tree() (in p_proto1/test)
==12771== by 0x804899F: main (in p_proto1/test)
==12771==
==12771== LEAK SUMMARY:
==12771== definitely lost: 8 bytes in 1 blocks.
==12771== possibly lost: 0 bytes in 0 blocks.
==12771== still reachable: 1280 bytes in 1 blocks.
==12771== suppressed: 0 bytes in 0 blocks.
==12771== Reachable blocks (those to which a pointer was found) are not
shown.
==12771== To see them, rerun with: --show-reachable=yes