Do I need a delete in the constructor too?

W

William Payne

Hi, I have a class that allocates some memory dynamically in its (only)
constructor. In my destructor I have a call to delete which corresponds to
the new in the constructor. So far so good. Anyway, after I've allocated the
memory that I need in my constructor I proceed to call a function in a
third-party library. If that function fails, I need to throw an exception
because the object relies on it to succeed. Now my question is: If I throw
an exception in my constructor, do I have to deallocate my memory there too
or is the destructor enough? I'm guessing the destructor won't be called if
I throw in my constructor (because then the object isn't created and cannot,
naturally, be destroyed), thus I have to take care to deallocate any
dynamically allocated memory in my constructor if it's going to throw an
exception. Correct?

/ WP
 
G

Gregg

succeed. Now my question is: If I throw an exception in my
constructor, do I have to deallocate my memory there too or is the
destructor enough? I'm guessing the destructor won't be called if I
throw in my constructor (because then the object isn't created and
cannot, naturally, be destroyed), thus I have to take care to
deallocate any dynamically allocated memory in my constructor if it's
going to throw an exception. Correct?

The destructor only runs when a fully constructed object is destroyed. If
you throw an exception within the constructor, the destructor will not be
called. You are correct that you will have to clean up before throwing the
exception. You may be able to consolidate the cleanup in a private function
that you can call from both the destructor and the constructor. You can
simplify the logic if you remember that deleting a null pointer is valid
and does not do anything.

Gregg
 
D

Daniel T.

William Payne said:
Hi, I have a class that allocates some memory dynamically in its (only)
constructor. In my destructor I have a call to delete which corresponds to
the new in the constructor. So far so good. Anyway, after I've allocated the
memory that I need in my constructor I proceed to call a function in a
third-party library. If that function fails, I need to throw an exception
because the object relies on it to succeed. Now my question is: If I throw
an exception in my constructor, do I have to deallocate my memory there too
or is the destructor enough? I'm guessing the destructor won't be called if
I throw in my constructor (because then the object isn't created and cannot,
naturally, be destroyed), thus I have to take care to deallocate any
dynamically allocated memory in my constructor if it's going to throw an
exception. Correct?

You need to delete the memory yourself in this case. I suggest you use a
vector (if the memory is an array) or wrap the memory in an auto_ptr so
that it will be deleted automatically if there is a throw in the c_tor.
 
J

John Harrison

William Payne said:
Hi, I have a class that allocates some memory dynamically in its (only)
constructor. In my destructor I have a call to delete which corresponds to
the new in the constructor. So far so good. Anyway, after I've allocated
the memory that I need in my constructor I proceed to call a function in a
third-party library. If that function fails, I need to throw an exception
because the object relies on it to succeed. Now my question is: If I throw
an exception in my constructor, do I have to deallocate my memory there
too or is the destructor enough? I'm guessing the destructor won't be
called if I throw in my constructor (because then the object isn't created
and cannot, naturally, be destroyed), thus I have to take care to
deallocate any dynamically allocated memory in my constructor if it's
going to throw an exception. Correct?

/ WP

Correct, the rule is that only fully constructed objects have their
destructors called.

This is another reason not to use pointers. Consider

class P
{
public:
P()
{
ptr = new int[100];
try
{
third_party(ptr); // might throw
}
catch (...)
{
delete[] ptr;
throw;
}
}
~P()
{
delete[] ptr;
}
// plus copy ctor and assignment op
private:
int* ptr;
};

class V
{
public:
V() : vec(100)
{
third_party(&vec[0]); // might throw
}
private:
vector<int> vec;
}

See how much simpler the constructor is in class V. In this class if
third_party throws an exception then V::vec will be destroyed because it is
a fully constructed object (even though V itself is not).

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
474,175
Messages
2,570,947
Members
47,498
Latest member
yelene6679

Latest Threads

Top