Suppose I create a form using a pointer and that form contains sub item as another pointer, when I delete the form, I perform a delete operation on the main pointer, do I need to perform a delete operation on the sub pointer also or the compiler does that on its own?
If you're the one allocating memory for the pointer, yes, you need to explicitly release all memory you're allocating.
struct A
{
};
struct B
{
A* a;
B() { a = new A; }
~B();
};
B* b = new B;
delete b;
//you will have a memory leak here, since the memory pointed to by b.a
//is not released
The proper way is freeing the memory in the destructor:
struct B
{
A* a;
B() { a = new A; }
~B() { delete a; }
};
You should read up on smart pointers, they might suit your case better.
Yes, you'll normally need to delete that explicitly to avoid a memory leak. Simple rule: if you used new to allocate it, you'll need a matching delete to free it.
That said, you usually want to use something like a smart pointer that handles all this automatically.
This question hinges on the way the destructor for the form is written. For example, the form may try to call the destructor for the sub-form. If it performs this kind of cleanup then you do not need to further release the sub-form. It would be informative to know what form management system you are talking about (for example MFC).
Related
Say I have something like this:
a = new A();
a->b = new B();
a->b->c = new C();
If I call:
delete(a)
Would it also delete b and c from memory? How can I be sure that all of them are gone?
This is a question that came up in one of my college classes, made by another student. No more info is given. I guess there is no definitive answer then, because I cannot tell you about the A,B or C destructors
Use
class A
{
std::shared_ptr<B> b;
}
You don't need destructor for A or B. Default ones will do.
Create destructor for A and B.
use smart pointer std::unique_ptr (or std::shared_ptr).
if you have such code in your program:
a = new A();
a->b = new B();
a->b->c = new C();
you need to (re)learn how to program in C++ properly. Member b of a and member c of b should be initialized by their constructor, not directly. When you write a constructor that use dynamic memory you should immediately think about memory management - either through smart pointers or properly following rule of three/five/zero
After you do that there would be no question if memory would be cleaned properly when a is destroyed.
Would it also delete b and c from memory?
Only if A's destructor contains code to explicitly do that or if b is some kind of smart pointer that takes care of it (and can accept the assignment). E.g.:
class A {
B *b;
~A() {
delete b;
}
};
How can I be sure that all of them are gone?
Presumably you're asking about best practices for avoiding leaks.
Don't use naked new/delete.
The entity responsible for allocating resources should always also be responsible for deallocating them.
Use RAII.
Without any info on how the destructors are defined, then it is true that there is no definitive answer. If there are no explicitly defined destructors, then the default destructors are used, and the code would cause memory leaks. If destructors are properly defined for those classes, then yes, delete(a) should delete b and c from memory.
So in other words, if something like this is defined in the code:
B::~B() { delete c; }
A::~A() { delete b; }
then the answer is yes. If not, the answer is no. If you don't know, then the answer is you can't know.
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.
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();
}
Lets say we have a class that holds a pointer member to another object. If I delete that pointer in the destructor I get an error (and I understand why).
My question is : is it possible to overcome that without memory leaks ?
Here is a demo of what I am doing.
class A {
public:
~A() { cout<< "~A()" <<endl; }
};
class B {
A *pA;
public:
B(A* pA) {
this->pA = pA;
}
~B() {
delete pA;
cout<<"~B()"<<endl;
}
};
int main() {
A a;
{
B b2(new A()); //deletes A, deletes B, no memory leaks
}
{
B b(&a); //deletes A, error.
}
return 0;
}
First of all that's not memory leak, but an undefined behavior, a more serious issue. An attempt is made to deallocate a memory from wrong region.
One should use delete/delete[]/free() only on corresponding new/new[]/malloc().
There is no full proof and architecture independent way, just adhere to good programming practices.
May not be perfect always, but one way is to overload new and delete and hold a std::map like data structure. Whenever new is called add the pointer to it. Upon delete you can make check if the pointer exists or not, if the allocation was of type new or new[] etc..
Definitely this will affect your performance, so you need to keep it under debug mode.
You have two objects that think they own a dynamically allocated object and try to delete it. The solution is to decide who should own the object, and to implement the correct copy/assignment behaviour with the help of the appropriate smart pointer:
Do A and B deal with dynamically allocated objects at all? There is no way of knowing this from a raw pointer, so the design has to be revised to cover one case or the other. Assuming dynamic object allocation, then
Each object owns its own copy: Implement the rule of three in A or B, and have only one of the two delete. You can use a scoped pointer to simplify memory management (boost_scoped_ptr, or std::unique_ptr).
Unique ownership: a single object owns the copy: Use std::unique_ptr. Disallow copy and assignment, allow move-copy and move-assignment
Shared ownership: Nobody/everybody owns the object. It gets deleted when nobody references it: use std::shared_ptr
You must tell B, when it owns the pointer and when it doesn't.
Add an additional flag telling when
class B {
bool owner;
A *pA;
public:
B(A* pA, bool bOwner) : owner(bOwner) {
this->pA = pA;
}
~B() {
if (owner)
delete pA;
cout<<"~B()"<<endl;
}
};
int main() {
A a;
{
B b2(new A(), true); //deletes A, destroys B, no memory leaks
}
{
B b(&a, false); //destroys B, ok.
}
return 0;
}
Must I free structure memory after using it? I have sample code:
struct aa
{
int a;
char * b ;
aa()
{
a=0;
b= new char[255];
}
} ;
aa *ss = new aa[3];
void fill()
{
aa * ssss = new aa;
aa * sss = new aa;
sss->a=10;
ss[0] = *sss;
cout<<ss[0].a<<"\n";
ss[1] = *sss;
cout<<ss[1].a<<"\n";
cout<<ssss[1].a<<"\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
fill();
delete(ss);
}
Must I do delete(ssss) at the end of fill?
Must I delete ss array of structure at the end of main?
Must I create destruct or to structure ss that frees *b memory?
What about classes is it the same logic?
Must I do delete(ssss) at the end of fill?
Yes, you must delete anything created with new. However, there's no need to use new here, just make it automatic:
void fill() {
aa ssss; // automatically destroyed on exit from the function
}
Must I delete ss array of structure at the end of main?
Yes, but it is an array, so must be deleted as an array:
delete [] ss;
^^
But again, there's no reason for this to be dynamically allocated:
aa ss[3]; // automatically destroyed on exit from the program
Must I create destruct or to structure ss that frees *b memory?
If you really want to use a raw pointer to manage the dynamic array, then yes. You will also need to think about a copy constructor and copy-assignment operator (per the Rule of Three) to make the class safe to use. Alternatively, use a smart pointer or container to manage the memory for you:
struct aa
{
int a;
std::vector<char> b ;
aa() : a(0), b(255) {}
} ;
What about classes is it the same logic?
Yes, the rule is always the same: anything created with new must be destroyed with delete. Managing objects is much easier if you avoid dynamic allocation where possible, and use smart pointers, containers and other RAII classes when you really do need it.
If you use new, you must use delete to avoid a memory leak. If you declare a variable on stack, it will be freed automatically when you exit the scope.
void something();
{
aa b = new aa();
// Do something
delete b; // You must use delete
}
void something();
{
aa b();
// Do something
// You don't have to use delete
}
In your specific case, it is not strictly necessary to use delete, because the program is going to terminate anyway and all the assigned memory will be freed by the OS.
It is still a good practice to do so, so as to be consistent (though there are some specific cases where you DON'T want to do this because freeing a lot of complex objects can take some time thus slowing down the program termination).
Anyhow, using naked pointers is not such a good idea in C++ since there are many so-called smart pointers (such as shared_ptr and unique_ptr) that take care of calling the destructor and freeing the memory after they run out of scope.
PS: In your code, you will have a memory leak, because the aa structure uses new inside the constructor and does not call delete in destructor.
YES
Please, please, please free your memory. I won't go into detail here, but take a look at this answer:
Can a memory block allocated by using operator new/malloc persist beyond end of program execution?
Rule of thumb in C/C++:
Allocated with new? free the memory with delete
Allocated with malloc, calloc, realloc? free the memory with free(void*)