Destructor not called

M

manitu

Hello all,

I am writing a kind of encapsulation of SQL statements in C++ as a
class. I am encountering problems that the destructor of my class
never gets called.

The class should be used as a kind of hierarchical representation of
the different SQL operations such as AND, OR and possible values.

I will post some abbreviated / shortened / simplified (partiyll
pseude) code here.

#include <stdio.h>
#include <stdlib.h>

class SQL
{
public:
SQL(int someOperator); // lets say 0=AND, 1=OR
SQL(char * someString); // lets say we only now AND, OR and
strings
~SQL();

SQL & operator & (SQL & param);

// public for testing purposes
int type; // lets say 0=Operator, 1=String
int value_operator;
char * value_string;
};


SQL::~SQL()
{
printf("I am the destructor\n");
};


SQL::SQL(int someOperator)
{
printf("I am the constructor for operators, my type is %i\n",
someOperator);

type = 0;
value_operator = someOperator;
};


SQL::SQL(char * someString)
{
printf("I am the constructor for string values, my value is
\"%s\"\n", someString);

type = 1;
value_string = someString;
};


SQL & SQL::eek:perator & (SQL & param)
{
return * new SQL( 1 );
};


void showType( SQL & sql )
{
printf("TYPE: %i\n", sql.type);
};




int main()
{
SQL test1("Test 1");

showType( test1 );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 1"
TYPE: 1
I am the destructor





int main()
{
showType( * new SQL("Test 2") & * new SQL("Test 3") );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 3"
I am the constructor for string values, my value is "Test 2"
I am the constructor for operators, my type is 1
TYPE: 0







I cannot explain why there are constructor calls for the three
instances of SQL, but no destructor calls.

Any help would be appreciated.


Thanks
Manuel
 
M

Mike Wahler

manitu said:
Hello all,

I am writing a kind of encapsulation of SQL statements in C++ as a
class. I am encountering problems that the destructor of my class
never gets called.

The class should be used as a kind of hierarchical representation of
the different SQL operations such as AND, OR and possible values.

I will post some abbreviated / shortened / simplified (partiyll
pseude) code here.

#include <stdio.h>
#include <stdlib.h>

class SQL
{
public:
SQL(int someOperator); // lets say 0=AND, 1=OR
SQL(char * someString); // lets say we only now AND, OR and
strings
~SQL();

SQL & operator & (SQL & param);

// public for testing purposes
int type; // lets say 0=Operator, 1=String
int value_operator;
char * value_string;
};


SQL::~SQL()
{
printf("I am the destructor\n");
};


SQL::SQL(int someOperator)
{
printf("I am the constructor for operators, my type is %i\n",
someOperator);

type = 0;
value_operator = someOperator;
};


SQL::SQL(char * someString)
{
printf("I am the constructor for string values, my value is
\"%s\"\n", someString);

type = 1;
value_string = someString;
};


SQL & SQL::eek:perator & (SQL & param)
{
return * new SQL( 1 );
};


void showType( SQL & sql )
{
printf("TYPE: %i\n", sql.type);
};




int main()
{
SQL test1("Test 1");

showType( test1 );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 1"
TYPE: 1
I am the destructor





int main()
{
showType( * new SQL("Test 2") & * new SQL("Test 3") );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 3"
I am the constructor for string values, my value is "Test 2"
I am the constructor for operators, my type is 1
TYPE: 0







I cannot explain why there are constructor calls for the three
instances of SQL, but no destructor calls.

In your second 'main()' example, since you dynamically allocated
your objects but never deleted them, they were never 'officially'
destroyed. So the dtors were not invoked. (The ones in the first
'main()' were because the objects had automatic storage duration).

And the way you've written your second 'main()', the objects cannot
be deleted, since you've left no way to determine their addresses
(which are needed as the argument to delete). Your code has a 'memory
leak'. The absence of the dtor calls serves as a warning of this in
this case.


-Mike
 
D

David Harmon

On 29 Oct 2004 09:02:59 -0700 in comp.lang.c++, (e-mail address removed)
(manitu) wrote,
I cannot explain why there are constructor calls for the three
instances of SQL, but no destructor calls.

You allocated them with new, but then you did not delete them.
For every new, you should write a corresponding delete.
 
L

Larry Brasfield

manitu said:
Hello all,

I am writing a kind of encapsulation of SQL statements in C++ as a
class. I am encountering problems that the destructor of my class
never gets called.

The class should be used as a kind of hierarchical representation of
the different SQL operations such as AND, OR and possible values.

I will post some abbreviated / shortened / simplified (partiyll
pseude) code here.

#include <stdio.h>
#include <stdlib.h>

class SQL
{
public:
SQL(int someOperator); // lets say 0=AND, 1=OR
SQL(char * someString); // lets say we only now AND, OR and
strings
~SQL();

SQL & operator & (SQL & param);

// public for testing purposes
int type; // lets say 0=Operator, 1=String
int value_operator;
char * value_string;
};


SQL::~SQL()
{
printf("I am the destructor\n");
};


SQL::SQL(int someOperator)
{
printf("I am the constructor for operators, my type is %i\n",
someOperator);

type = 0;
value_operator = someOperator;
};


SQL::SQL(char * someString)
{
printf("I am the constructor for string values, my value is
\"%s\"\n", someString);

type = 1;
value_string = someString;
};


SQL & SQL::eek:perator & (SQL & param)
{
return * new SQL( 1 );
};


void showType( SQL & sql )
{
printf("TYPE: %i\n", sql.type);
};




int main()
{
SQL test1("Test 1");

showType( test1 );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 1"
TYPE: 1
I am the destructor





int main()
{
showType( * new SQL("Test 2") & * new SQL("Test 3") );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 3"
I am the constructor for string values, my value is "Test 2"
I am the constructor for operators, my type is 1
TYPE: 0







I cannot explain why there are constructor calls for the three
instances of SQL, but no destructor calls.

Any help would be appreciated.


Thanks
Manuel

I would recommend a basic C++ reference.
You need to understand the difference between
dynamic allocation and other kinds before you
use C++ in any serious way. To put the present
puzzle simply, it is up to the programmer to get
new and delete operations to match up. You
have not done so.
 
J

John Harrison

manitu said:
Hello all,

I am writing a kind of encapsulation of SQL statements in C++ as a
class. I am encountering problems that the destructor of my class
never gets called.

The class should be used as a kind of hierarchical representation of
the different SQL operations such as AND, OR and possible values.

I will post some abbreviated / shortened / simplified (partiyll
pseude) code here.



int main()
{
showType( * new SQL("Test 2") & * new SQL("Test 3") );

return 0;
};


=============> outputs

I am the constructor for string values, my value is "Test 3"
I am the constructor for string values, my value is "Test 2"
I am the constructor for operators, my type is 1
TYPE: 0

Just rewrite like this

showType( SQL("Test 2") & SQL("Test 3") );

No calls to new. But this will only work if you rewrite operator& in the way
that you should have in the first place

SQL operator & (const SQL & param) const;

Not the addition of const and that operator& no longer returns a reference.

These changes will problably require some other changes that should have
been written in the first place, for instance a copy constructor and an
assignment operator and proper const correctness on other methods.

I cannot explain why there are constructor calls for the three
instances of SQL, but no destructor calls.

Because you use new but never called delete. But in the example above you
didn't need to use new at all.

You're not a Java programmer are you? In any case you need a book to teach
you how to program C++ properly, you are going down so many wrong paths
simultaneously that it not surprising you are in a mess. I would recommend
Effective C++ by Scott Meyers.

john
 
J

John Harrison

Just rewrite like this

showType( SQL("Test 2") & SQL("Test 3") );

No calls to new. But this will only work if you rewrite operator& in the way
that you should have in the first place

SQL operator & (const SQL & param) const;

Not the addition of const and that operator& no longer returns a reference.

Oh and showType should be rewritten like this

void showType( const SQL & sql )

Again note the addition of const.

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top