473,396 Members | 2,009 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Smartpointers and throwing an exception from the constructor

This has bugged me for some time now, and I havent have the time to discuss it before, so guys please tell me what you think.

We all know we can use smart pointers in C++ to take charge of automatic deallocation of objects created in the heap, we know the smart pointer will save the address allocated with "new", and that smart pointers will call "delete" when going out of scope:
Expand|Select|Wrap|Line Numbers
  1.    ...
  2.   SmartPointer< Foo > foo = new Foo();
  3.   ...
  4.   }//<--- Automatic deallocation
  5.  
So far so good.

But what if a constructor of class Foo throws an exception?
Will a memory allocation take place? If so, the exception will keep the smart pointer from receiving the newly allocated pointer, so when the smart pointer goes out of scope, the allocated memory wont get deleted!

What is the best way to avoid leaking memory in this case?
Oct 22 '07 #1
6 1498
weaknessforcats
9,208 Expert Mod 8TB
But what if a constructor of class Foo throws an exception?
Will a memory allocation take place? If so, the exception will keep the smart pointer from receiving the newly allocated pointer, so when the smart pointer goes out of scope, the allocated memory wont get deleted!

What is the best way to avoid leaking memory in this case?
Let's see, your concern is that that new operator will throw a bad_alloc and never return to assign the address to the smart pointer.

I presume you would:
Expand|Select|Wrap|Line Numbers
  1. SmartPointer<Foo> foo;
  2. try
  3. {
  4.   foo = new Foo();
  5. }catch (exception whoops)
  6. {
  7.      //necessary handling.
  8. }
  9.  
In this scenario, foo is created with no object. Hence the managed pointer is null. No problem. Smart pointers can be unattached to an object.

In the above code, the assignment occurs only if new returns.

Otherwise, foo remains unattached. When it goes out of scope it will be deleted normally.

Check out the article on Handle Classes in the C/C++ Articles forum.
Oct 22 '07 #2
Let's see, your concern is that that new operator will throw a bad_alloc and never return to assign the address to the smart pointer.
Actually my concern is: what if the constructor throws an exception, Im not talking about bad_alloc. I am referring to a case where the memory is allocated succesfully but the constructor throws an exception.

Expand|Select|Wrap|Line Numbers
  1. class Foo
  2. {
  3.    public: Foo( )
  4.     {
  5.      if ( somethingTerriblyWrongHappens )
  6.            throw someException();
  7.     }
  8. }
  9.  
Oct 23 '07 #3
Banfa
9,065 Expert Mod 8TB
Subscribing .
Oct 23 '07 #4
weaknessforcats
9,208 Expert Mod 8TB
Actually my concern is: what if the constructor throws an exception, Im not talking about bad_alloc. I am referring to a case where the memory is allocated succesfully but the constructor throws an exception.
Same procedure:
Expand|Select|Wrap|Line Numbers
  1. Foo* fptr;
  2. try
  3. {
  4.   fptr= new Foo();
  5. }catch (exception whoops)
  6. {
  7.      //necessary handling.
  8.      //consider abortin your program
  9.     //or maybe set fptr to zero.
  10. }
  11.  
In any case, remember that when an exception is thrown inside a constructor, all of the constructors of the data members have already been called. Therefore, before you get your catch block, the destructors on all those data members have been called and the object itself has been deleted from memory.

All that you may have to do is delete any allocations you made in your constructor since the destructor of the object being built will not be called. Also, if you use an initializer list, you may need a function try block so you can catch any exceptions thrown by the code called in the initializer list.
Oct 23 '07 #5
Same procedure:
Expand|Select|Wrap|Line Numbers
  1. Foo* fptr;
  2. try
  3. {
  4.   fptr= new Foo();
  5. }catch (exception whoops)
  6. {
  7.      //necessary handling.
  8.      //consider abortin your program
  9.     //or maybe set fptr to zero.
  10. }
  11.  
In any case, remember that when an exception is thrown inside a constructor, all of the constructors of the data members have already been called. Therefore, before you get your catch block, the destructors on all those data members have been called and the object itself has been deleted from memory.

All that you may have to do is delete any allocations you made in your constructor since the destructor of the object being built will not be called. Also, if you use an initializer list, you may need a function try block so you can catch any exceptions thrown by the code called in the initializer list.
Excelent answer, time to do some code testing.
Oct 23 '07 #6
weaknessforcats
9,208 Expert Mod 8TB
All that you may have to do is delete any allocations you made in your constructor since the destructor of the object being built will not be called.
To do this you would put a try/catch block inside the construcor so you could catch any exceptions that are thrown. Inside the catch block (you are still inside the constructor) you clean up any allocations you made in the constructor and then re-throw the exception.

A function try block is a different thing:
Expand|Select|Wrap|Line Numbers
  1. MyClass::MyClass(int a, int b)
  2. try
  3.       : mymember(a,b);     //in case this throws.
  4. {
  5.      //this is the normal constructor
  6. }
  7. catch (etc...)
  8. {
  9.     //this is the catch for the exception in the initializer list
  10. }
  11.  
I didn't know if I was clear on this.
Oct 24 '07 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: Eric Lilja | last post by:
Hello, in my program I have a function (pseudo code): void start_mysql_service() { obtain handle start mysql service using handle if start fails close handle and throw an exception...
3
by: Scott Brady Drummonds | last post by:
Hi, all, I've a fairly small piece of code that is causing me problems. I'm using std::string and am building a string of several dozen characters using several of std::string's functions: a...
21
by: mihai | last post by:
People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object. What about copy constructors? How...
11
by: mangesh | last post by:
I read , FAQ : 17.4] How should I handle resources if my constructors may throw exceptions? Above faq says that use smart pointer in construcors . Because if exception is thrown from constructor...
15
by: Sek | last post by:
Gurus, I am wondering whether it is right to throw an exception from a Property of an object. To get into it further, is it okay to throw exception during 'get' operation? I was searching...
40
by: Sek | last post by:
Is it appropriate to throw exception from a constructor? Thats the only way i could think of to denote the failure of constructor, wherein i am invoking couple of other classes to initialise the...
6
by: Marvin Barley | last post by:
I have a class that throws exceptions in new initializer, and a static array of objects of this type. When something is wrong in initialization, CGI program crashes miserably. Debugging shows...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.