If I delete a class, are its member variables automatically deleted? - c++

I have been researching, and nothing relevant has come up, so I came here.
I am trying to avoid memory leaks, so I am wondering:
Say I have class MyClass with member ints a and b, and an int array c, which are filled in a member function:
class MyClass
{
public:
int a, b;
int c[2];
void setVariables()
{
a, b = 0;
for (int i = 0; i < 2; i++)
{
c[i] = 3;
}
}
};
int main(int argc, char* argv[])
{
MyClass* mc = new MyClass();
mc->setVariables();
delete mc;
}
Now, after I call delete mc, will a, b, and all the contents of c be deleted as well? Or will I have to do that explicitly in the destructor of MyClass?

The rule is very simple: every object created with new must be destroyed exactly once with delete; every array created with new[] must be destroyed exactly once with delete[]; everything else must not be deleted. So your code is correct; you are deleting mc after creating it with new, and not deleting the members which were not created with new.
Applying the rule can be quite tricky when the program flow gets complicated (especially when exceptions are involved); for that reason, it is much better not to delete objects yourself, but to immediately use the result of new to initialise a smart pointer to manage the object for you.

When delete mc is executed, the compiler calls the destructor of the object (MyClass::~MyClass()) and then deallocates the memory associated with it.
The default destructor (when you don't declare your own) calls the destructors of all member variables, in order from last to first by declaration (that is, in this case, c, then b, then a). Since those members in this example are POD types (they do not have a destructor), no work is done.

Class members are a part of the class' memory structure.
So when you free that memory, the members are freed with it.
NOTE:
If you have pointers they are destroyed too, BUT the memory they point at isn't destroyed.
More about class memory consumption:
C++ Classes

Variables inside of a class have class scope and are destroyed when the class is. The only thing you need to worry about is pointers -- those will need to be addressed appropriately in your destructor.

For your specific example, the answer is yes. That's because you allocated the member variables on the stack. If you had used new to allocate memory for the member variables the answer would be no and would require you to explicitly delete the member variables in the class' destructor.
class MyClass(): heapVariabl(NULL)
{
MyClass()
{}
~MyClass()
{
delete heapVariable;
}
int a, b;
int[2] c;
int *heapVariable;
void setVariables()
{
a, b = 0;
heapVariable = new int; // <- requires deletion in destructor to free memory
*heapVariable = 0;
for (int i = 0; i < 2; i++)
{
c[i] = 3;
}
}
}

When you free an object, all of its member variables are automatically freed as well. So, in your case, yes, a, b and c are all freed.
However, if one of your member variables is a pointer, only the pointer itself is automatically freed, not the object it points to - this is the most common case for having to write your own destructor.

delete will reclaim the memory that your object contains. If your type maintains pointers to dynamically allocated memory then you will need to clean those up inside of your destructor.
As for your specific quesiton:
after I call delete mc, will a, b, and all the contents of c be deleted as well? Or will I have to do that explicitly in the destructor of MyClass?
They will be cleaned up for you as they were not allocated dynamically.

Your three variables were not allocated with new so there would be no need to delete them at all.
They would be destructed when your class is deleted (as they were allocated when your class was newd), but that's not the same as being deleted.

Related

Using a base class as a safe container for pointers

So I was looking at this question Memory Allocation Exception in Constructor where my boss states in his beautiful answer that the destructor will not be called.
Which makes me wonder,
If I were to write
struct XBase
{
int* a;
char* b;
float* c;
XBase() : a(nullptr), b(nullptr), c(nullptr) {}
~XBase()
{
delete[] a; delete[] b; delete[] c;
}
};
and
struct X : XBase
{
X() {
a = new int[100];
b = new char[100];
c = new float[100];
}
}
Then, if the allocation of c fails (with an exception being thrown), then the destructor of XBase would be called, since the base class has been constructed.
And no memory leak?
Am I correct?
You are right; this will work, because:
By the time X constructor body is executed, XBase is already constructed, and its destructor will be called.
Doing delete or delete[] on null pointers is perfectly valid, and does nothing.
So, if the allocation of a, b or c fails, the destructor of XBase will deallocate everything.
But, obviously, this design makes you write much more code that needed, since you can simply use std::vector or std::unique_ptr<T[]>.
Just to have a formal version here to back up the claims,
ยง 15.2/2
An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects [...].
If you're concerned about the memory allocation failing, I would put it in a separate method, like a Build or Create. You could then let the destructor handle it if it has been initialized (but definitely check pointer before blindly delete-ing.
Another solution is smart pointers, which are not designed to fit this case necessarily, but do automatically deallocate their contents.

segmentation fault at the end of the destructor on deleting integer pointer

I am trying to understand the below program . While executing am getting errors as shown below.
#include<iostream>
using namespace std;
class Base
{
public:
int *a;
int a1;
int b;
Base(){
cout<<"Inside Constructor"<<endl;
a1 = 10;
a = &a1;
cout<<" "<<a<<endl;
b = 20;
}
Base(const Base &rhs)
{
cout<<"Inside Copy Constructor"<<endl;
a = new int;
*a = *(rhs.a);
b = rhs.b;
}
~Base(void)
{
cout<<"Inside destructor"<<endl;
delete a;
}
};
int main()
{
Base obj;
Base obj2(obj);
cout<<"obj a "<<*(obj.a)<<" b "<<obj.b<<endl;
cout<<"obj2 a "<<*(obj2.a)<<" b "<<obj2.b<<endl;
obj.a1 = 30;
obj.b = 40;
cout<<"obj a "<<*(obj.a)<<" b "<<obj.b<<endl;
cout<<"obj2 a "<<*(obj2.a)<<" b "<<obj2.b<<endl;
return 0;
}
While executing this code i am getting the following output
Inside Constructor
Inside Copy Constructor
obj a 10 b 20
obj2 a 10 b 20
obj a 30 b 40
obj2 a 10 b 20
Inside destructor
Inside destructor
Segmentation fault
[EDIT]
I was looking for a way to destruct the heap memory that i have created in copy constructor . So what can be done here ? please suggest
[EDIT]
delete should be used on memory allocated from heap using new only.
a1 = 10;
a = &a1;
In your case "a" is holding the address of memory in stack. So, you shouldn't call delete on that memory.
You have to delete memory acquired with new (dynamically allocated), not to an automatic-storage variable.
In copy constructor you are using new operator to assign the memory for pointer a ,so u can delete it.But since u are not using new operator in default constructor, you can delete the pointer a .
You must use delete opearator to free the memory of variable which is in heap not in stack.
when you use new operator ,the variable is created in heap where as local variable are created in stack memory which can't be delete using delete operator
The problem is not the copy constructor, the problem is that you don't consistently use new (if you used move then maybe you would have a point). You have some options. I am trying to be useful, not exhaustive, maybe I'm missing other good design ideas.
Use new always (and consistently)
You can put a new in all the constructors, and thus, the destructor would always be able to call to delete. Even when you don't need it. It may be a ugly hack, but is consistent.
Never use new
If you never use new, you don't use delete either and the compiler ensures consistency and ensures that you don't mess up. Normally, you can rely on the compiler default behaviour on constructors.
Use smart pointers
If instead of calling to delete manually you save the variable inside a unique_ptr, then it will be deallocated at the destructor automatically by the compiler. The smart pointer is smart enough to know if it is initialized.
Beware that using a smart pointer means that you should never call delete, because if you do so without warning the smart pointer, you will stumble onto the same problem. If you are not familiarized with them and you are using C++11, it is a nice thing to learn :)
Track the status of your pointers
I would not vouch for this. It seems very C and not C++. However, you can always track a bool value and at destroy time check it. This is just like using smart pointers, but with an in-house implementation. I think that it is a bad design idea, although educational in some cases.

C++ Pointers and Deletion

This is a simplified version of some code that I have. Since pointerB in class A is set to pointer, beta, in the client code which points to allocated memory, would i have to free the memory pointed by pointerB in the destructor of class A once it is deleted as well?
class A{
public:
A(B* beta){
pointerB = beta;
}
~A(){
/*
would deleting pointerB be necessary
*/
}
B* pointerB;
};
class B{
public:
B();
};
//client code
B* beta = new B();
A* alpha = new A(beta);
//do stuff
delete beta;
delete alpha;
beta = NULL;
alpha = NULL;
For every new there has to be one and only one delete during the execution of your application.
So it doesn't matter whether delete pointerB is called in the destructor or delete beta is called outside as you did. Because it is the same memory that is freed here! The question is if A "owns" an instance of B (and thus is responsible for freeing the memory it uses) or if A only has a reference to an instance of B (and is for example deleted when beta is still used).
BUT (as Roger already pointed out) I suggest reading the documentation to std::shared_ptr and std::unique_ptr. Here for example: http://en.cppreference.com/w/cpp/memory In most cases you can make good use of these and then you don't have to care for memory management.
It looks like objects of type A retain a pointer to a B object but don't own a B. This is fine and A's destructor shouldn't attempt to delete the B object.
Given this model, the client should ensure that the B object passed by pointer to A's constructor remains in existence throughout the lifetime of the A object. Your client code fails to do this but if you completely avoid dynamically allocating objects, achieving this is simple and natural and removes any possibility of leaking objects.
E.g.
void client()
{
B b;
A a(&b);
// do stuff
// Because we constructed `a` after we constructed `b` in this scope
// we are guarateed that `a` will be destroyed before `b` (reverse order)
// and the pointer that `a` is holding will never point to a destroyed
// object.
}
The assignment in the constructor of A: pointerB = beta; does not allocate new memory. Therefore, you do not need to de-allocate it when calling the destructor of A.
However, this behavior is risky:
B* beta = new B(); // memory for B is allocated
A alpha( B ); // local instance. A.pointerB points to beta
delete beta; // memory de-allocated
// risky part: alpha.pointerB still points to where beta was allocated
// BUT THIS MEMORY IS ALREADY FREED!
You need to carefully think about this.
Your example can be simplified to this:
struct A{};
int main()
{
A* wtf= new A;
A* omg= wtf;
delete wtf;
}
Is correct and so is this:
struct A{};
int main()
{
A* wtf= new A;
A* omg= wtf;
delete omg;
}
Deleting both is a double delete error, don't do this:
delete omg;
delete wtf;
You would be trying to deallocate the same memory both pointers are pointing at, twice!
When you allocate memory dynamically you have to release it.
When you do new B() You allocate memory for the object dynamically and then assign the address to beta which is of type B*. This is a pointer to that memory. When you do delete beta, you delete the memory that was allocated. This memory can be pointed by many pointers (like the one in your constructor )BUT you need to delete only once. But if you make attempts to use the other pointers (dereferencing etc.) you can blow your code.
Only when you do new you allocate memory. [Your code must contain equal and corresponding number of delete] which has to be released
Consider this way, you have a place for storing data and several labels pointing to the location of that place. Now if using one label you destroy the place, the other labels will still be having the location. But now its useless since the place is inexistent now.
The whole idea is, if you allocate something from heap, you should deallocate it and it should be done only once, and, you shouldn't access the memory after it is deallocated.
In order to achieve this, we usually make allocation and deallocation to be done by same component. For example, if you allocate a piece of memory in class Foo, do the deallocation there too. However, it is only a convention to make things less error-prone. As long as you are sure that the deallocation is going to happen, and happen only once, everything is fine.
Using shared_ptr or similar facilities is also a way to ensure this behavior.
Going back to your specific example, we cannot say whether you should do the deallocation in A. What I can say is, as you have delete beta done in your main() already, if you do the deallocation both in A and main() then it is a problem.
Whether you should deallocate in A or leave it to the caller depends on your design.
You have to delete it in destructor of A. There is a sample program you can test both conditions by
1. Run the program still value of b exists means you have to delete it in destructor of A.
2. Uncomment delete b line in the code and you will see b is free.
class B;
class A
{
B * b;
public:
A(B * obj)
{
b = obj;
}
~A()
{
//delete b;
}
};
class B
{
int value;
public:
B()
{
value = 10;
}
~B()
{
}
int getValue(){return value;}
};
void main()
{
B *b = new B;
A * a = new A(b);
delete a;
cout<<"B exists: "<<b->getValue();
}

Will memory of array member of a class be allocated?

I wonder whether memory for array member of a class be allocated in c++.
In my class, I defined array member like this:
class A
{
public:
B* B_array[1000];
}
and, in the constructor, I want to use it:
A::A()
{
for(int i = 0; i < 1000; i++)
{
B_array[i] = new B;//can i use B_array[0...999]???
}
}
B* B_array[1000];
What you have is an array of 1000 pointers to the type B.
for(int i = 0; i < 1000; i++)
{
B_array[i] = new B;//can i use B_array[0...999]???
}
Allocates memory to each pointer in the array, after this statement each pointer points to a memory on heap.
So yes you can use each of them, once this code is executed.
Yes, you can. When you enter the body of constructor, there are 1000 uninitialized pointers waiting for you to initialize them.
What you should do, though, is use std::vector<B>
class A
{
public:
std::vector<B> array;
}
A::A() : array(1000) {}
and be done with it. Vector allocates its elements dynamically.
Yes you can. Memory for 1000 pointers will be allocated always. However those pointers will not be initialised unless you do that yourself (as you are in your contructor code).
I wonder whether memory for array member of a class be allocated in c++
Yes, why not. If your doubt is about allocating an array the way you are doing, it is possible. If your doubt is about calling B's constructor while still being in A's constructor, then also there is absolutely no issues with that.
In general, however there are several things that I would take care in the code shown e.g. not hard coding the value 1000, checking for exception from new etc.. you get the idea.
And you should also be bothered about releasing the memory resource in the destructor of A explicitly.
Yes, the memory for 1000 pointers of B class instances will be allocated. You have defined an array B_array[1000] of B* objects. It's the same as int integerArray [1000]. You just store pointers in the array, not values.
However you will need to initialize them to point to the actual objects on the heap.

Why doesn't the C++ default destructor destroy my objects?

The C++ specification says the default destructor deletes all non-static members. Nevertheless, I can't manage to achieve that.
I have this:
class N {
public:
~N() {
std::cout << "Destroying object of type N";
}
};
class M {
public:
M() {
n = new N;
}
// ~M() { //this should happen by default
// delete n;
// }
private:
N* n;
};
Then this should print the given message, but it doesn't:
M* m = new M();
delete m; //this should invoke the default destructor
What makes you think the object n points to should be deleted by default? The default destructor destroys the pointer, not what it's pointing to.
Edit: I'll see if I can make this a little more clear.
If you had a local pointer, and it went out of scope, would you expect the object it points to to be destroyed?
{
Thing* t = new Thing;
// do some stuff here
// no "delete t;"
}
The t pointer is cleaned up, but the Thing it points to is not. This is a leak. Essentially the same thing is happening in your class.
Imagine something like this:
class M {
public:
M() { }
// ~M() { // If this happens by default
// delete n; // then this will delete an arbitrary pointer!
// }
private:
N* n;
};
You're on your own with pointers in C++. No one will automatically delete them for you.
The default destructor will indeed destroy all member objects. But the member object in this case is a pointer itself, not the thing it points to. This might have confused you.
However, if instead of a simple built-in pointer, you will use a smart pointer, the destruction of such a "pointer" (which is actually a class) might trigger the destruction of the object pointed to.
The default destructor is destroying the pointer. If you want to delete the N with M's default destructor, use a smart pointer. Change N * n; to auto_ptr<N> n; and n will be destroyed.
Edit: As pointed out in comments, auto_ptr<> is not the best smart pointer for all uses, but it looks like what's called for here. It specifically represents ownership: the N in an M is there for the duration of the M and no longer. Copying or assigning an auto_ptr<> represents a change in ownership, which is usually not what you want. If you wanted to pass a pointer from M, you should pass a N * gotten from n.get().
A more general solution would be boost::shared_ptr<>, which will be in the C++0x standard. That can be used pretty much wherever a raw pointer would be used. It's not the most efficient construct, and has problems with circular references, but it's generally a safe construct.
Another edit: To answer the question in another comment, the standard behavior of the default destructor is to destroy all data members and base classes. However, deleting a raw pointer simply removes the pointer, not what it points to. After all, the implementation can't know if that's the only pointer, or the important one, or anything like that. The idea behind smart pointers is that deleting a smart pointer will at least lead to the deletion of what it points to, which is usually the desired behavior.
Is there any reason why you use a pointer when the pointed-to object seems to belong the contained object? Just store the object by value:
class M
{
N n;
public:
M() : n()
{
}
};
It is incorrect to say that the destructor deletes members. It invokes the destructor of each member (and base class), which for built-in types (like pointers) means doing nothing.
Matching news with deletes is your responsibility (either manually, or with the help of smart pointers).
Your argument might seem sound but that's not how things work for pointers.
n is actually being destructed but, what this means is that the N* destructor is being called which, it does NOT destruct whatever object n is pointing to. Think of the N*'s destructor as if it were an int's destructor. It deletes its value, the same happens for a pointer, it deletes the address it is pointing to, but it doesn't need to delete whatever object is located at the address you just deleted.
I think you may be confused about levels of indirection here. When an instance is destroyed, each data member does indeed get destroyed along with it. In your case, when an M is destroyed and M::~M() is called, its variable n really is destroyed. The problem is that n is a N *, so while the pointer is destroyed, the thing it points to is not.
delete does not work like this. Consider your simple statement:
delete n;
The above statement destroys the thing that n points to, which is an object of type N. It does not destroy n itself, which is an N * pointer.
There is a very good reason that M::~M() does not automatically call delete n; which is this: the N object referred to might be shared between several M objects, and if one M were destroyed, the rest would lose the N they were pointing at, leaving horrible dangling pointers everywhere. C++ does not attempt to interpret what you meant to do with your pointers, it just does what you told it to do.
In short, M really is destroying all of its members when it is destroyed, it's just that this destruction doesn't do what you think it should do. If you want a pointer type which takes ownership of an object and destroys it when the pointer is destroyed, look at std::auto_ptr.
The default destructor looks like this:
~M()
{
}
The default destructor does not insert code to do anything with pointed-to things. What if you had n pointing to a stack variable? Automatically inserting a delete n would crash.
The default destructor calls the destructor on each member of the class (member.~T()). For a pointer, that's a no-op (does nothing), just like myint.~int() does nothing, but for member classes with defined destructors, the destructor is called.
Here's another example:
struct MyClass {
public:
MyClass() { .. } // doesn't matter what this does
int x;
int* p;
std::string s;
std::vector<int> v;
};
The default destructor in reality is doing this:
MyClass::~MyClass()
{
// Call destructor on member variables in reverse order
v.~std::vector<int>(); // frees memory
s.~std::string(); // frees memory
p.~int*(); // does nothing, no custom destructor
x.~int(); // does nothing, no custom destructor
}
Of course, if you define a destructor, the code in your destructor runs before the member variables are destroyed (obviously, otherwise they would not be valid!).
Try avoiding using pointers. They are last resort elements.
class N {
public:
~N() {
std::cout << "Destroying object of type N";
}
};
class M {
public:
M() {
// n = new N; no need, default constructor by default
}
// ~M() { //this should happen by default
// delete n;
// }
private:
N n; // No pointer here
};
Then use it this way
main(int, char**)
{
M m;
}
This will display Destroying object of type N
I think you could benefit from a very simple example:
int main(int argc, char* argv[])
{
N* n = new N();
} // n is destructed here
This will not print anything either.
Why ? Because the pointer (n) is destructed, not the object pointed to *n.
Of course, you would not want it to destroy the object pointed to:
int main(int argc, char* argv[])
{
N myObject;
{
N* n = &myObject;
} // n is destructed here, myObject is not
myObject.foo();
} // myObject is destructed here
You should remember that unlike languages like C# or Java, there are 2 ways to create objects in C++: directly N myObject (on the stack) or via new like in new N() in which case the object is placed on the heap and YOU are reponsible for releasing it at a later time.
So your destructor destroys the pointer, but not the object pointed to. Allocate the object without new (and without using a pointer) or use a Smart Pointer if you want it to be automatic.
M destructor should have 'delete n'.
Since you are using new to create instance, it won't delete by default.
class N {
public:
~N() {
std::cout << "Destroying object of type N";
}
};
class M {
public:
M() {
n = new N;
}
// ~M() { //this should happen by default
// delete n;
// }
private:
N* n;
};
and now the expectation is :
M* m = new M();
delete m; //this should invoke the default destructor
It will only happen, if the class M is derived from N:
class M: Class N {
...
Only in this situation,
M* m = new M()
will call constructor of N and then constructor of M, where as
delete m;
will automatically call destructor of M first and then N