Re: Best way to allocate memory in the constructor
salvatore benedetto wrote:
What's the best way to allocate memory in the constructor and avoid
memory leaks if the constructor fails?
Use std::vector<>.
Let's say that in my constructor, I have to allocate memory
with malloc (i.e. an array of char *)several times, and one
of them fails.
Well, in that case you have to be prepared to undo each and every allocation
before throwing bad_alloc. However, I would try to avoid multiple
allocations or use std::vector anyway.
Anyhow, there is one technique which makes this a bit easier: you defer each
allocation to a separate object (like std::vector, duh!). The compiler then
constructs each object in turn, allocating memory in each object's ctor but
also invokes already-constructed objects' dtors if one of them fails.
What's the best way to deallocate the previously allocated memory?
Use some kind of RAII, which is again an argument towards separating each
allocation to its own object (did I mention std::vector yet?).
Is the destructor being called if I "return" in the middle of
the constructor body?
Returning in the middle is in no way special. If you return, the object is
considered fully constructed now.
If not, is it a good idea to call explicity the constructor in order
to clean the memory?
Huh? I guess you might have meant the dtor here. Still, you shouldn't do
that either.
At the moment, I simply check every allocation and if the check fails
I deallocate all the memory previously allocated, but this produces
a lot of code duplication.
Example:
if ((first = (char *)malloc(sizeof(....)) == NULL)
return;
if ((second = (char *)malloc.... )) == NULL) {
free(first); return;
}
if ((third = (int *)malloc... )) == NULL) {
free(second);
free(first);
return;
}
// and so on!
First thing is that you should use the ctor's initialiser list. You use that
to allocate each element with the appropriate memory.
Then, in the body, you check all elements and if one of them is null, you
invoke free() on all the others that are non-null and throw an exception.
Note: all of this is needless hassle, just write a class that behaves like a
pointer to char/int/whatever and additionally allows allocating a single
buffer with malloc(). Use that class instead of plain malloc() with
pointers. Well, if you don't absolutely need malloc(), you could also use
std::vector to do just that (and a lot more), but writing such a
malloc-based buffer is actually a good exercise.
Uli
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]