Will the below code cause memory leak in c++ - c++

class someclass {};
class base
{
int a;
int *pint;
someclass objsomeclass;
someclass* psomeclass;
public:
base()
{
objsomeclass = someclass();
psomeclass = new someclass();
pint = new int();
throw "constructor failed";
a = 43;
}
}
int main()
{
base temp();
}
In the above code, the constructor throws. Which objects will be leaked, and how can the memory leaks be avoided?
int main()
{
base *temp = new base();
}
How about in the above code? How can the memory leaks be avoided after the constructor throws?

Yes it will leak memory. When the constructor throws, no destructor will be called (in this case you don't show a destructor that frees the dynamically allocated objects, but lets assume you had one).
This is a major reason to use smart pointers - since the smart poitners are full fledged objects, they will get destructors called during the exception's stack unwind and have the opportunity to free the memory.
If you use something like Boost's scoped_ptr<> template, your class could look more like:
class base{
int a;
scoped_ptr<int> pint;
someclass objsomeclass;
scoped_ptr<someclass> psomeclass;
base() :
pint( new int),
objsomeclass( someclass()),
psomeclass( new someclass())
{
throw "constructor failed";
a = 43;
}
}
And you would have no memory leaks (and the default dtor would also clean up the dynamic memory allocations).
To sum up (and hopefully this also answers the question about the
base* temp = new base();
statement):
When an exception is thrown inside a constructor there are several things that you should take note of in terms of properly handling resource allocations that may have occured in the aborted construction of the object:
the destructor for the object being constructed will not be called.
destructors for member objects contained in that object's class will be called
the memory for the object that was being constructed will be freed.
This means that if your object owns resources, you have 2 methods available to clean up those resources that might have already been acquired when the constructor throws:
catch the exception, release the resources, then rethrow. This can be difficult to get correct and can become a maintenance problem.
use objects to manage the resource lifetimes (RAII) and use those objects as the members. When the constructor for your object throws an exception, the member objects will have desctructors called and will have an opportunity to free the resource whose lifetimes they are responsible for.

Both new's will be leaked.
Assign the address of the heap created objects to named smart pointers so that it will be deleted inside the smart pointers destructor that get call when the exception is thrown - (RAII).
class base {
int a;
boost::shared_ptr<int> pint;
someclass objsomeclass;
boost::shared_ptr<someclass> psomeclass;
base() :
objsomeclass( someclass() ),
boost::shared_ptr<someclass> psomeclass( new someclass() ),
boost::shared_ptr<int> pint( new int() )
{
throw "constructor failed";
a = 43;
}
};
Now psomeclass & pint destructors will be called when the stack unwind when the exception is thrown in the constructor, and those destructors will deallocate the allocated memory.
int main(){
base *temp = new base();
}
For ordinary memory allocation using (non-plcaement) new, memory allocated by the operator new is freed automatically if the constructor throws an exception. In terms of why bother freeing individual members (in response to comments to Mike B's answer), the automatic freeing only applies when an exception is thrown in a constructor of an object being new'ly allocated, not in other cases. Also, the memory that is freed is those allocated for the object members, not any memory you might have allocated say inside the constructor. i.e. It would free the memory for the member variables a, pint, objsomeclass, and psomeclass, but not the memory allocated from new someclass() and new int().

I believe that the top answer is wrong and would still leak memory.
The destructor for the class members will not be called if the constructor throws an exception (because it never completed its initialization, and perhaps some members have never reached their constructor calls).
Their destructors are only called during the class's destructor call. That only makes sense.
This simple program demonstrates it.
#include <stdio.h>
class A
{
int x;
public:
A(int x) : x(x) { printf("A constructor [%d]\n", x); }
~A() { printf("A destructor [%d]\n", x); }
};
class B
{
A a1;
A a2;
public:
B()
: a1(3),
a2(5)
{
printf("B constructor\n");
throw "failed";
}
~B() { printf("B destructor\n"); }
};
int main()
{
B b;
return 0;
}
With the following output (using g++ 4.5.2):
A constructor [3]
A constructor [5]
B constructor
terminate called after throwing an instance of 'char const*'
Aborted
If your constructor fails partway then it is your responsibility to deal with it. Worse, the exception may be thrown from your base class' constructor!
The way to deal with these cases is by employing a "function try block" (but even then you must carefully code the destruction of your partially initialized object).
The correct approach to your problem would then be something like this:
#include <stdio.h>
class A
{
int x;
public:
A(int x) : x(x) { printf("A constructor [%d]\n", x); }
~A() { printf("A destructor [%d]\n", x); }
};
class B
{
A * a1;
A * a2;
public:
B()
try // <--- Notice this change
: a1(NULL),
a2(NULL)
{
printf("B constructor\n");
a1 = new A(3);
throw "fail";
a2 = new A(5);
}
catch ( ... ) { // <--- Notice this change
printf("B Cleanup\n");
delete a2; // It's ok if it's NULL.
delete a1; // It's ok if it's NULL.
}
~B() { printf("B destructor\n"); }
};
int main()
{
B b;
return 0;
}
If you run it you will get the expected output where only the allocated objects are destroyed and freed.
B constructor
A constructor [3]
B Cleanup
A destructor [3]
terminate called after throwing an instance of 'char const*'
Aborted
You can still work it out with smart shared pointers if you want to, with additional copying. Writing a constructor similar to this:
class C
{
std::shared_ptr<someclass> a1;
std::shared_ptr<someclass> a2;
public:
C()
{
std::shared_ptr<someclass> new_a1(new someclass());
std::shared_ptr<someclass> new_a2(new someclass());
// You will reach here only if both allocations succeeded. Exception will free them both since they were allocated as automatic variables on the stack.
a1 = new_a1;
a2 = new_a2;
}
}
Good luck,
Tzvi.

If you throw in a constructor, you should clean up everything that came before the call to throw. If you are using inheritance or throwing in a destructor, you really shouldn't be. The behaviour is odd (don't have my standard handy, but it might be undefined?).

Yes, that code will leak memory. Blocks of memory allocated using "new" are not freed when an exception is raised. This is part of the motivation behind RAII.
To avoid the memory leak, try something like this:
psomeclass = NULL;
pint = NULL;
/* So on for any pointers you allocate */
try {
objsomeclass = someclass();
psomeclass = new someclass();
pint = new int();
throw "constructor failed";
a = 43;
}
catch (...)
{
delete psomeclass;
delete pint;
throw;
}

Everything you "new" needs to be deleted, or you'll cause a memory leak. So these two lines:
psomeclass = new someclass();
pint = new int();
Will cause memory leaks, because you need to do:
delete pint;
delete psomeclass;
In a finally block to avoid them being leaked.
Also, this line:
base temp = base();
Is unnecessary. You just need to do:
base temp;
Adding the "= base()" is unnecessary.

you need to delete psomeclass... Its not necessary to clean up the integer...
RWendi

Related

Destructor to call free() to free dynamically allocated memory using malloc

In C++, if I have some dynamically allocated memory using malloc, can I free the same by calling free() from destructor and then explicitly call the destructor via class object?
Trying to do that but getting an exception.
Is it now allowed?
So here I'm explicitly calling the destructor. Is this allowed? I mean, I'm calling it to free memory. I did read that after the scope, the destructor is called implicitly. Does this mean the free() will try to happen twice?
My code snippet:
class School
{
int a;
};
class Test
{
public:
School* school;
void Run()
{
school = (School*)malloc(sizeof(School));
}
~Test()
{
if (NULL != school)
{
free(school);
school = NULL;
}
}
};
int main()
{
Test t;
t.Run();
t.~Test();
return 0;
}
Your code destroys t twice. It is destroyed first when you call the destructor and then again when it goes out of scope. You cannot create one object and then destroy two objects.
You can explicitly call the destructor, and that has sense whenever you create the object using an placement new.
You may get an exception if you have the opposite order of operations. First you need to call the destructor, as it needs to free all the resources that the object may have allocated. You need to call the free function only after all resources of the object are deallocated/destroyed. For example:
struct S {
~S() {
delete ptr;
}
int *ptr;
};
int main() {
char *buf = (char*) malloc(sizeof(S)) ;
S *s = new (buf)S();
// Do not call free here as the destructor needs to access the s.ptr:
//free(buf);
s->~S();
free(buf);
return 0;
}

How the destructor is called for heap object without delete operator?

Can somebody explain here how destructor is called for object created in heap via new operator when the corresponding delete is not called.
In addition since in below code we are catching object via const reference and in destructor we are changing object value (i.e. setting n=0), so how is that possible.
class A
{
private:
int n;
public:
A()
{
n=100;
std::cout<<"In constructor..."<<std::endl;
}
~A()
{
n=0;
std::cout<<"In destructor..."<<std::endl;
}
};
int main()
{
try
{
throw *(new A());
}
catch(const A& obj)
{
std::cout<<"Caught...."<<std::endl;
}
return 0;
}
Output from program (running on http://cpp.sh/3jm4x):
In constructor...
Caught....
In destructor...
throw makes a copy of the object, which is then destroyed automatically after catch. It is this destruction that you observe. The original heap-allocated object is indeed never destroyed.
You actually have a memory leak, because the destructor that is called is not for the object allocated by new.
throw *(new A()); results in a copy of the object and you can see that the copy constructor is called. And this is the object that the destructor is called for at the end of the scope for catch.
You can check the live demo here.

Constructor finishes by throwing an exception ? Is there a memory leak?

I was going over this article
and it states
Note: if a constructor finishes by throwing an exception, the memory
associated with the object itself is cleaned up — there is no memory
leak. For example:
void f()
{
X x; // If X::X() throws, the memory for x itself will not leak
Y* p = new Y(); // If Y::Y() throws, the memory for *p itself will not leak
}
I am having difficulty understanding this and would appreciate it if someone could clarify this. I tried the following example which shows that incase of an exception inside a constructor the destructor would not be called.
struct someObject
{
someObject()
{
f = new foo();
throw 12;
}
~someObject()
{
std::cout << "Destructor of someobject called";
}
foo* f;
};
class foo
{
public:
foo()
{
g = new glue();
someObject a;
}
~foo()
{
std::cout << "Destructor of foo";
}
private:
glue* g;
};
int main()
{
try
{
foo a;
}
catch(int a)
{
//Exception caught. foo destructor not called and someobject destrucotr not called.
//Memory leak of glue and foo objects
}
}
How would I fix this issue ?
Sorry for the inconvenience the update might have caused.
"... the destructor would not be called."
Since the object isn't considered as constructed yet, after the constructor failed with an exception, the destructor won't be called.
Object allocation, and construction (merely destruction) are different things.
Any objects allocated using new() before the exception is thrown will leak.
You shouldn't manage these resources yourself, unless you're really, really, really need it, and are about 100% sure about what you're doing.
Rather use suitable smart pointers for class members from the standard dynamic memory management library.
When the constructor throws, no destructor will be called. When an
exception is thrown inside a constructor there are several things that
you should take note of in terms of properly handling resource
allocations that may have occured in the aborted construction of the
object:
the destructor for the object being constructed will not be called.
destructors for member objects contained in that object's class will be called
the memory for the object that was being constructed will be freed.

Uncaught exception at constructor after allocating memory

I've read that awesome summary of Michael Burr regarding a constructor that throws an exception, here: Will the below code cause memory leak in c++
My question is: Is the behavior similar when an exception is thrown by a function called from constructor? i.e. in case that the exception isn't caught where it was thrown and thus it climbs up to the constructor and further to the function that called to the constructor.
I'm especially interested to know what about the member objects contained in that object's class, will their destructors be called? More specifically, in my case it's about a member of type boost::shared_ptr.
Consider the following example:
class A {
A() { throw some_exception }
};
class B {
B() { A a = new A(); }
};
class C {
boost::shared_ptr<B> p2b;
int i;
int *pint;
someclass objsomeclass;
someclass* psomeclass;
public:
C() {
objsomeclass = someclass();
psomeclass = new someclass();
pint = new int();
p2b(new B);
}
};
void foo()
{
C c();
}
main()
{
foo();
}
Will the destructor of p2a be called?
I'll appreciate if you could point me to an appropriate and reliable resource that covers this case.
Assuming you change the code so it compiles, the destructor of p2a (now p2b) will be called because it was successfully default-constructed. However, it will still hold NULL, because your attempt to reset it in the body of C::C fails.
The memory allocated by new B will be cleaned up automatically by the stack unwinding process. However, pint and psomeclass will both be leaked, because you're not using RAII for these members.
To clarify, let's step through the code:
C::C() {
objsomeclass = someclass();
psomeclass = new someclass();
pint = new int();
p2b.reset(new B);
/* in your code as posted, the call sequence is:
new B (allocate sizeof B)
-> B::B
-> new A (allocate sizeof A)
-> A::A which throws
<- new A failed, so memory is freed
<- B::B failed (initialized subobjects would be
destroyed here, but there are none)
new B failed, so memory is freed
*/
}
Note that:
all members are already default-initialized (because you didn't use the initializer list), so they all get destroyed when the body of C::C unwinds
if psomeclass and pint were smart pointers, this would release their dynamically-allocated memory. They aren't, so this is leaked.
In general, it is better style to use the initializer list and RAII.
For reference, maybe start with this (very old) article: GOTW 66

C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4]

Thanks for all the response.
I reformatted my question to understand the state of the member pointer after the containg class constructor throws an exception
Again my example class :)
class Foo
{
public:
Foo()
{
int error = 0;
p = new Fred;
throw error; // Force throw , trying to understand what will happen to p
}
~Foo()
{
if (p)
{
delete p;
p = 0;
}
}
private:
Fred* p;
};
int main()
{
try
{
Foo* lptr = new Foo;
}
catch (...)
{}
}
The consturctor for class foo would throw an exception for some random reason. I understand that the desturctor of foo will never be called but in this case will the destructor for p get called?
what difference it makes to have p as a boost smart pointer than a raw pointer to fred.
Thanks.
There is a similar question here that covers what your asking.
In this case, if the call to new fails, then the memory for the pointer is guaranteed to be freed. If the call succeeds, and the constructor throws after that, you will have a memory leak.
The destructor of the class will not be called, because the object was never fully constructed. There are two ways to fix this.
1)
Have exceptions fully managed in the constructor:
class Foo
{
public:
Foo()
try
{
p = new p;
throw /* something */;
}
catch (...)
{
delete p;
throw; //rethrow. no memory leak
}
private:
int *p;
};
2)
Or use a smart pointer. When a constructor is entered, all of its members have been constructed. And because when a constructor throws, and objects members have been constructed, they must be destructed. And a smart pointer fixes that:
class Foo
{
public:
Foo() :
p(new int)
{
throw /* something */;
}
private:
std::auto_ptr<int> p;
};
Not if it was never allocated.
But instead of NULL being returned by bad allocations via new, you will get an exception std::bad_alloc.
NULL gets returned by C malloc if an allocation cannot be made.
You are also correct that if an object is not fully constructed, it will not be destructed. So if you have a successful allocation on the heap in a constructor, and then an exception is thrown, that will lead to a memory leak.
You could also consider having a zombie state instead of throwing an exception. Some of the standard C++ library does this. In which case the object is not in a valid state and can be checked if it is in a valid state via another method.
Generally throwing exceptions in constructors is best though.
See my answer here for an extended discussion.
The destructor for p will not be called, if the memory allocation for p fails.
The question really doesn't make any sense. new Fred(); will never return NULL. It will only ever either successfully create a Fred object, or throw an exception. If it threw an exception, the Fred object would never have existed, so it's destructor would not be called.