Jump to content
  • Advertisement
Sign in to follow this  

Destructor not being invoked?

This topic is 4733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Anyone know why the destructor doesnt get called?  I thought when the reference 
count was 0 it automatically gets called.  When I take out pc2.printInfo() 
(last line of call() ), it calls the destructor.  Anyone know why that happens?


#include <iostream>
using namespace std;

class PointerClass{
      public:
             PointerClass(int val, char *str){
             ip = new int(val);
             cs = str;          
             }
             void blankVal(){ *ip = 0; cs = '\0'; }
             void printInfo(){ cout << "*ip = " << *ip << endl << "cs = " << cs << endl; }
             ~PointerClass(){
                             cout << "deleting ip " << endl;
                             delete ip;
             }
             
             PointerClass(const PointerClass &);
             private:             
             int *ip;
             char *cs;             
};

inline PointerClass::PointerClass(const PointerClass &pc){
       ip = new int(*(pc.ip));
       cs = (pc.cs);       
}
void call();
int main(){
    
   call();
    
    
    
}

void call(){
    PointerClass pc(50,"Hello");
    pc.printInfo();
    PointerClass pc2(pc);
    pc2.printInfo();
    pc2.blankVal();
    pc.printInfo();
    pc2.printInfo();
}

Share this post


Link to post
Share on other sites
Advertisement
I'm surprised the thing doesn't just crash. When you run blankVal on pc2, you have the following line:

cs = '\0';

This is setting the value of cs to 0, ie, it is now invalid. Later on in printInfo, you're trying to output the contents of that string, which should give you an access violation. There are quite a few pitfalls with the way you're handling this string. I'd suggest you look at std::string, or some other string class to handle this.

Quote:
I thought when the reference count was 0 it automatically gets called.

No. C++ doesn't have automatic garbage collection. In this case, the destructor will be called automatically when that object goes out of scope (IE, when call returns), if that's what you meant. If you allocate memory off the heap however, using the new keyword, it will remain allocated until you use delete to free it. If you loose all references to it (ie, the reference count is 0), it will still not be destroyed. It will remain allocated until your program terminates.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nemesis2k2
I'm surprised the thing doesn't just crash. When you run blankVal on pc2, you have the following line:

cs = '\0';

This is setting the value of cs to 0, ie, it is now invalid. Later on in printInfo, you're trying to output the contents of that string, which should give you an access violation. There are quite a few pitfalls with the way you're handling this string. I'd suggest you look at std::string, or some other string class to handle this.

Quote:
I thought when the reference count was 0 it automatically gets called.

No. C++ doesn't have automatic garbage collection. In this case, the destructor will be called automatically when that object goes out of scope (IE, when call returns), if that's what you meant. If you allocate memory off the heap however, using the new keyword, it will remain allocated until you use delete to free it. If you loose all references to it (ie, the reference count is 0), it will still not be destroyed. It will remain allocated until your program terminates.


Why is it an access violation?

My question was about why the destructor wasn't being called, if I take out the last line in call then it calls the destructor, if it stays in call(), the destructor isn't invoked.

When it leaves scope, there are no references, so it should be called, it isn't referenced in main either. When call() is done, I dont see why the destructor isnt called.

Share this post


Link to post
Share on other sites
Quote:
Why is it an access violation?

cs is a pointer to a character. When you set its location in the constructor, you are directing that pointer to the location of an already existing character, in this case, the start of the constant string "Hello". When you set it to 0 in the blackVal() function, you are directing that pointer to the location 0. You don't have a character, or a string, or any other kind of data that belongs to your program at location 0. When you try and read or write to this location, it will cause an access violation, as your program doesn't have the rights to access that area.

Quote:
My question was about why the destructor wasn't being called, if I take out the last line in call then it calls the destructor, if it stays in call(), the destructor isn't invoked.

What IDE are you using? In Visual Studio, that function won't even return. The whole program will crash with an access violation as soon as you try and print the string cs is pointing to. Any problems you're having are undoubtedly related to this problem (hence why they disappear when you remove that function call).

Quote:
When it leaves scope, there are no references, so it should be called, it isn't referenced in main either. When call() is done, I dont see why the destructor isnt called.

It isn't a matter of whether or not there are any references to it. Even if there were references to it somewhere, the destructor would still be called. It's a local variable,and it's going out of scope, therefore it will be destroyed. The fact that it's not is related to the problem above I'm sure.


I strongly suggest you read up on some fundamentals of C++, specifically pointers and scope rules.

Share this post


Link to post
Share on other sites
From what I read, whenever the reference count is 0(an object going out of scope decrements the reference count), the destructor is called. Its right last time I checked btw.

I didnt know nulling an object would screw up a program, in java it just prints out the word null if it doesnt contain valid data. I use G++ and wasn't getting any access violations or anything. But yeah that solves it, it obviously got some error and just exited the function blocks since my print statements werent working.

Share this post


Link to post
Share on other sites
Nemesis2k is right. There is no reference count in C++ (unless you use Managed C++). There is in Java, but this isn't Java. You have to clean up after yourself.

delete ip; when you're done with it.

Of course, if you didn't use new to allocate memory for the object, but created it on the stack, it will get deleted when it goes out of scope.


PointerClass *pg = NULL;

void SomeFunction ()
{
PointerClass *p1 = new PointerClass (5, "foo");
PointerClass p2 (24, "bar");

pg = &p2;

//p1 was allocated using new and must be deleted
delete p1;
/*
p2 was created on the stack and is destroyed automatically.
pg is therefore now INVALID. C++ doesn't care about p2 still being
referenced!
*/

}




Find a tutorial on C++ memory management. It is quite different from Java. (Personally, I found Java's method far less intuitive, but maybe that's just me).

Share this post


Link to post
Share on other sites
i dont normally use new on built in data types, but wanted to test out copy constructors, thanks for the advice anyway

Share this post


Link to post
Share on other sites
I'll try to answer your question...
Are you sure the destructor isn't invoked? Because from the looks of your destructor, it just prints a line, calls on the delete operator and exits. So, if you didn't put cin.get() or something similar to that (or you could step throught the program), you won't see anything (probably just a flash of the console or something).

Otherwise, nothing else seems wrong with the way the destructor is constructed (save the previous comments).

{Edit} as a follow up... don't try to print a null pointer, instead do something like this:
			 void printInfo(){ 
cout << "*ip = ";
if ( ip )
cout << ip;
else
cout << "NULL";
cout << endl;
cout << "cs = " << cs << endl;
}


and instead of assigning cs to '\0' (a character literal), assign it to "\0" (a string literal) which will make it point to a string containing a null terminator instead of making it point to 0...

[Edited by - SnT2k on June 6, 2005 4:36:00 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!