Exception handling in C++
-
Hi all, What is wrong in this problem. Is this the right way to handle? #include class MyErrorClass { char *reason; int *i; public: MyErrorClass(char *r) { i = new int[6]; cout<<;"Constructor<<endl; reason = r; cout<<reason<<<endl; } char* giveReason() { return reason; } ~MyErrorClass() { cout<<"destructor"<<endl; delete[] i; } }; void main() { try { throw MyErrorClass("error"); } catch (MyErrorClass &e) { cout<<"Exception caught --- <<e.giveReason()<<endl; } } Thanks San
I hope you got a crash when you run this code snippet. I rewrote it like this. It allocates the MyErrorClass then throw it. On the top level function, you can delete it. Check the code snippet.
void main()
{try
{
throw new MyErrorClass("error");
}
catch (MyErrorClass* e)
{
cout<<"Exception caught --- "<<e->giveReason()<<endl;
delete e;
}
}[Added] As pointed out by Stuart, it will be better to catch the exception object by reference itself. But here the problem is your MyErrorClass is not well written to handle its allocation which can cause crashes(I had). Hope you've already went thought Stuart's explanations. Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
modified on Friday, December 19, 2008 9:46 AM
-
I hope you got a crash when you run this code snippet. I rewrote it like this. It allocates the MyErrorClass then throw it. On the top level function, you can delete it. Check the code snippet.
void main()
{try
{
throw new MyErrorClass("error");
}
catch (MyErrorClass* e)
{
cout<<"Exception caught --- "<<e->giveReason()<<endl;
delete e;
}
}[Added] As pointed out by Stuart, it will be better to catch the exception object by reference itself. But here the problem is your MyErrorClass is not well written to handle its allocation which can cause crashes(I had). Hope you've already went thought Stuart's explanations. Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
modified on Friday, December 19, 2008 9:46 AM
Ummm - no. You definitely should not get a crash when you throw an exception object (as opposed to an exception pointer). The exception declaration does not define the lifetime of the exception - the runtime copies it (or something like that, anyway). Try the following - you'll find it doesn't crash...
#include <stdexcept> #include <iostream> int main(int, char**) { try { throw std::runtime_error("Test"); } catch(std::exception& e) { std::cerr << "Caught exception - " << e.what() << std::endl; }; }
-
Hi all, What is wrong in this problem. Is this the right way to handle? #include class MyErrorClass { char *reason; int *i; public: MyErrorClass(char *r) { i = new int[6]; cout<<;"Constructor<<endl; reason = r; cout<<reason<<<endl; } char* giveReason() { return reason; } ~MyErrorClass() { cout<<"destructor"<<endl; delete[] i; } }; void main() { try { throw MyErrorClass("error"); } catch (MyErrorClass &e) { cout<<"Exception caught --- <<e.giveReason()<<endl; } } Thanks San
Looks fine to me, aside from some formatting errors that cause compile-time errors. Ignore the comments telling you to throw pointers to exception objects - throw the exception objects directly. You may also want to derive from
std::exception
orstd::runtime_error
, to leverage the standard C++ exception classes? Here's a minimal example of throwing exceptions with standard C++ exception classes:#include <stdexcept> #include <iostream> int main(int, char**) { try { throw std::runtime_error("Test"); } catch(std::exception& e) { std::cerr << "Caught exception - " << e.what() << std::endl; }; }
modified on Friday, December 19, 2008 8:35 AM
-
Ummm - no. You definitely should not get a crash when you throw an exception object (as opposed to an exception pointer). The exception declaration does not define the lifetime of the exception - the runtime copies it (or something like that, anyway). Try the following - you'll find it doesn't crash...
#include <stdexcept> #include <iostream> int main(int, char**) { try { throw std::runtime_error("Test"); } catch(std::exception& e) { std::cerr << "Caught exception - " << e.what() << std::endl; }; }
Well Stuart, try with this code snippet. Its the same code snippet provided by Ron. I made it compilable. I'll be surprised if it didn't crashed in your system.
class MyErrorClass
{char *reason;
int *i;public:
MyErrorClass(char *r)
{
i = new int[6];
cout<<"Constructor"<<endl;
reason = r;
cout<<reason<<endl;}
char* giveReason()
{
return reason;
}
~MyErrorClass()
{
cout<<"destructor"<<endl;
delete[] i;
}};
void main()
{try
{
throw MyErrorClass("error");
}
catch (MyErrorClass* e)
{
cout<<"Exception caught --- "<<e->giveReason()<<endl;
}
}Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
-
Well Stuart, try with this code snippet. Its the same code snippet provided by Ron. I made it compilable. I'll be surprised if it didn't crashed in your system.
class MyErrorClass
{char *reason;
int *i;public:
MyErrorClass(char *r)
{
i = new int[6];
cout<<"Constructor"<<endl;
reason = r;
cout<<reason<<endl;}
char* giveReason()
{
return reason;
}
~MyErrorClass()
{
cout<<"destructor"<<endl;
delete[] i;
}};
void main()
{try
{
throw MyErrorClass("error");
}
catch (MyErrorClass* e)
{
cout<<"Exception caught --- "<<e->giveReason()<<endl;
}
}Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
Yes, this code will crash - because you're throwing an object of type
MyErrorClass
and trying to catch a pointer to an object of typeMyErrorClass
. With the original code, which has this line, catching an object (well, reference to an object) of typeMyErrorClass`` catch (MyErrorClass &e)
the code compiles, links and runs as expected. Did you try it? I did. -
Yes, this code will crash - because you're throwing an object of type
MyErrorClass
and trying to catch a pointer to an object of typeMyErrorClass
. With the original code, which has this line, catching an object (well, reference to an object) of typeMyErrorClass`` catch (MyErrorClass &e)
the code compiles, links and runs as expected. Did you try it? I did.Ah! Sorry, i did send you the wrong code. I forgot to rollback the changes made to the old code. I really meant -
catch (MyErrorClass &e)
will also crash. I'm posting the code snippet once again. Well, I'm using Visual Studio 6.0. Which one you're using? Well, the reason for crash is due to the fact that MyErrorClass::i is being de-allocated twice, since the copy constructor is not written for deep copy.class MyErrorClass
{char *reason;
int *i;public:
MyErrorClass(char *r)
{
i = new int[6];
cout<<"Constructor"<<endl;
reason = r;
cout<<reason<<endl;}
char* giveReason()
{
return reason;
}
~MyErrorClass()
{
cout<<"destructor"<<endl;
delete[] i;
}};
void main()
{try
{
throw MyErrorClass("error");
}
catch (MyErrorClass& e)
{
cout<<"Exception caught --- "<<e.giveReason()<<endl;
}
}Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
-
Ah! Sorry, i did send you the wrong code. I forgot to rollback the changes made to the old code. I really meant -
catch (MyErrorClass &e)
will also crash. I'm posting the code snippet once again. Well, I'm using Visual Studio 6.0. Which one you're using? Well, the reason for crash is due to the fact that MyErrorClass::i is being de-allocated twice, since the copy constructor is not written for deep copy.class MyErrorClass
{char *reason;
int *i;public:
MyErrorClass(char *r)
{
i = new int[6];
cout<<"Constructor"<<endl;
reason = r;
cout<<reason<<endl;}
char* giveReason()
{
return reason;
}
~MyErrorClass()
{
cout<<"destructor"<<endl;
delete[] i;
}};
void main()
{try
{
throw MyErrorClass("error");
}
catch (MyErrorClass& e)
{
cout<<"Exception caught --- "<<e.giveReason()<<endl;
}
}Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
Jijo raj wrote:
Well, the reason for crash is due to the fact that MyErrorClass::i is being de-allocated twice, since the copy constructor is not written for deep copy
You're quite correct - I didn't get a crash because I compiled with a non-debug runtime library. Even so, I'd still recommend throwing objects, not pointers - the real solution is for the OP to write a better exception class, I think.
Jijo raj wrote:
I'm using Visual Studio 6.0. Which one you're using?
2003, 2005 and 2008 - certainly not VC6!!! The reason I don't use VC6 is because it is so primitive in terms of C++ language support.
-
Hi all, What is wrong in this problem. Is this the right way to handle? #include class MyErrorClass { char *reason; int *i; public: MyErrorClass(char *r) { i = new int[6]; cout<<;"Constructor<<endl; reason = r; cout<<reason<<<endl; } char* giveReason() { return reason; } ~MyErrorClass() { cout<<"destructor"<<endl; delete[] i; } }; void main() { try { throw MyErrorClass("error"); } catch (MyErrorClass &e) { cout<<"Exception caught --- <<e.giveReason()<<endl; } } Thanks San
As Jijo says, you get a crash (if you're using the right runtime) because your exception object isn't written in such a way that it can be copied correctly. I would suggest changing
i
to be astd::vector<int>
andreason
to be astd::string
, because these can be copied successfully (unlike raw pointers to dynamically allocated memory). You also don't need to botherdelete
ing them. -
Jijo raj wrote:
Well, the reason for crash is due to the fact that MyErrorClass::i is being de-allocated twice, since the copy constructor is not written for deep copy
You're quite correct - I didn't get a crash because I compiled with a non-debug runtime library. Even so, I'd still recommend throwing objects, not pointers - the real solution is for the OP to write a better exception class, I think.
Jijo raj wrote:
I'm using Visual Studio 6.0. Which one you're using?
2003, 2005 and 2008 - certainly not VC6!!! The reason I don't use VC6 is because it is so primitive in terms of C++ language support.
Stuart Dootson wrote:
Even so, I'd still recommend throwing objects, not pointers - the real solution is for the OP to write a better exception class, I think.
You're right. Indeed, i did forget about C++ morels when i saw the crash. :((
Stuart Dootson wrote:
2003, 2005 and 2008 - certainly not VC6!!! The reason I don't use VC6 is because it is so primitive in terms of C++ language support.
Yep. That's right. But still my favorite due to the excellent fast IDE. Well, i'm waiting for VC10 which is supposed to be the new 6. :) Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
-
Stuart Dootson wrote:
Even so, I'd still recommend throwing objects, not pointers - the real solution is for the OP to write a better exception class, I think.
You're right. Indeed, i did forget about C++ morels when i saw the crash. :((
Stuart Dootson wrote:
2003, 2005 and 2008 - certainly not VC6!!! The reason I don't use VC6 is because it is so primitive in terms of C++ language support.
Yep. That's right. But still my favorite due to the excellent fast IDE. Well, i'm waiting for VC10 which is supposed to be the new 6. :) Regards, Jijo.
_____________________________________________________ http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
Jijo raj wrote:
still my favorite due to the excellent fast IDE
VS2003 and VS2005 are fast when you give them a 2.4GHz Core 2 Duo and 4GB of RAM to play with :-) VS2008...I'm not so fond of, the debugger especially seems sluggish.
Jijo raj wrote:
Well, i'm waiting for VC10 which is supposed to be the new 6.
It's not (IMO) - I've used the CTP, and it's a really an evolution of VS2008 - it did seem a bit quicker, though. And the compiler has C++0x features, like lambdas and type inferencing, which are uber-cool :-)