Jump to content
  • Advertisement
Sign in to follow this  
neverland

a question about exception

This topic is 4811 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

When an exception thrown, all the objects successfully constructed in the try block will be destroyed. But consider the following code:
#include <iostream>
using namespace std;

class A {
public:
	A() throw(int) {
		ID = count++;
		cout << "object ID:" << ID << " generated." << endl;	
		if (3 == ID)
			throw 0;	
	}
	~A() {
		cout << "object ID:" << ID << " destroyed." << endl;
	}
	
private:
	static int count;
	int ID;
};
int A::count = 0;

int main()
{
	try {
		A *a1 = new A;
		A *a2 = new A;
		A *a3 = new A[3];
		
		delete a1;
		delete a2;
		delete[] a3;
		
		cout << "Exit Now" << endl;
	} catch(int) {
		cout << "exception caught" << endl;
	}
}
The output is: object ID:0 generated. object ID:1 generated. object ID:2 generated. object ID:3 generated. object ID:2 destroyed. exception caught The first element in the a3 array is successfully destroyed but a1 and a2 not. Why? If I change the try block to the following code:
try {
	A a1;
	A a2;
	A *a3 = new A[3];
		
	delete[] a3;
		
	cout << "Exit Now" << endl;
}
The output is: object ID:0 generated. object ID:1 generated. object ID:2 generated. object ID:3 generated. object ID:2 destroyed. object ID:1 destroyed. object ID:0 destroyed. exception caught a1 and a2 are successfully destroyed. I am a little bit confused.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by neverland
The first element in the a3 array is successfully destroyed but a1 and a2 not. Why?


Because when the exception is thrown, all "local" variables are destroyed (the pointers, but not the point-ees) and then the code proceeds immediately to the catch() statement - the delete statements are never reached.

Also, you'll note that a3[0] is successfully created - your code throws attempting to construct a3[1]. In the interests of exception-safety, new[] backs out (deconstructs) a3[0] as well - there's no mechanism for dealing with partially constructed arrays.

If you want these objects destroyed (and you probably do) you need to use RAII. The standard library has a "smart pointer" called std::auto_ptr which should clean up all the normal pointers:

std::auto_ptr< A > a1( new A );
std::auto_ptr< A > a2( new A );

note: auto_ptr does NOT work with arrays because it uses delete instead of delete[]. It also has weird copying semantics - "copying" (misdominer) causes the "ownership" to be "transfered". A useful alternative to protect yourself from accidentally transfering ownership would be:

boost::scoped_ptr< A > a1( new A );

(see boost homepage). Boost also has an array equivilant to scoped_ptr:

boost::scoped_array< A > a3( new A[3] );

Share this post


Link to post
Share on other sites
The problem you're having is that in the first version, the variables are not on the stack. A variable on the stack (A someVariable) will be destroyed automatically when it goes out of scope (i.e. at the end of the try block or when an exception is thrown), whereas variables created on the heap (A* someVariable = new A;) must be deleted manually. Try this instead if you want to use the stack:

int main()
{
try
{
A a1;
A a2;
A a3[3];
cout << "Exit Now" << endl;
}
catch(int)
{
cout << "Exception caught" << endl;
}

return 0;
}



Or this version if you want to dynamically allocate the objects with <code>new</code>

int main()
{
A* a1 = NULL;
A* a2 = NULL;
A* a3 = NULL;

try
{
a1 = new A;
a2 = new A;
a3 = new A[3];

cout << "Exit Now" << endl;
}
catch(int)
{
cout << "Exception caught" << endl;
}

delete[] a3; // if the creation failed, this will
delete a2; // have no effect because the variables
delete a1; // were initialized to NULL
return 0;
}

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!