If an object exists as such:
MyClass obj;
To call a member function:
obj.myMemberFunction();
Then to call the destructor of that object after it fulfills its purpose:
delete obj;
However, lets say I have a pointer to an object:
MyClass* obj;
To call a member function:
obj->myMemberFunction();
Now... How do I call the destructor on this object?
You've got it backwards; do delete in the second case and not the first:
MyClass obj;
obj.myMemberFunction();
//delete obj;
//^^^^^^^^^^^
// NO! `obj` has automatic storage and will
// be destroyed automatically when it goes out
// of scope.
delete expects a pointer to a dynamically-allocated object:
MyClass* obj = new MyClass;
obj->myMemberFunction();
delete obj;
If you create it with
MyClass obj;
you do nothing to delete it. If you create it with
MyClass* obj = new MyClass();
you use
delete obj;
to delete it.
The operator delete is intended to be used with pointers that stores the adresses of areas allocated on the heap thanks to the corresponding operator new.
void function ()
{
int * pt;
pt = new int;
*pt = 42;
delete pt; // memory released
}
Memory allocated on the stack is automaticly released at the end of the corresponding scope :
void function ()
{
int i;
i = 42;
} // memory released
When you write MyClass obj;, the object is allocated on the stack, as opposed to on the heap. In this case, the object is destroyed automatically then it goes out of scope. The compiler generates code to ensure the destructor is called. So you don't delete the object explicitly.
delete is used when an object is allocated on the heap. For example:
MyClass* pobj = new MyClass;
// Do something with pobj...
delete pobj;
Related
InitMyObject(MyObject* ptr)
{
*ptr = MyObject();
}
struct Data
{
MyObject obj;
};
extern Data data;
// ...
InitMyObject(&data.obj);
delete &data.obj; // ? is this ok
How I can delete (call deconstructor) data.obj, I also try Data::obj as pointer (nullptr default) then pass the pointer but crashed on Init.
How I can delete (call deconstructor) data.obj
The destructor of data will destroy its subobjects. Since data has static storage, it is automatically destroyed at the end of the program.
delete &data.obj; // ? is this ok
No. You may only delete the result of a non-placement new expression. You may not delete a pointer to a member object.
Maybe the question is basic but I didn't found answer for that.
I will give the some examples (when Object has destructor), and I will glad to understand what happens in each one:
1)
int f (){
Object *p=new Object();
int something=5;
return something;
}
I think it would not call the destructor, but someone told me that if the function has return then the destructor will be called.
2)
Object & f (){
Object *p=new Object();
return *p;
}
How about now? is it connected to the object instance we return?
if 1) is not calling detractor please confirm that 3) is not calling the destructor (I still think it will not, but confirming)
3)
int f (){
for(int i=0; i<10; i++){
Object *p=new Object();
}
int something=5;
return something;
}
If 1) is calling the destructor: if 3) was void function, does the destructor
will be called (I again think not).
In case #1, the destructor is NOT called, because the object exists in dynamic (heap) memory, so it will not be destructed until delete is called on it. Every new needs a matching delete.
The destructor WOULD be called if the object were created in automatic (stack) memory instead, eg:
int f() {
Object p; // <-- no 'new'
int something=5;
return something;
} // <-- ~Object() is called here
In case #2, the destructor of the object pointed to by p is NOT called, and the return statement is returning a reference to the same object that exists in dynamic memory.
If the function returned an Object by value instead of by reference, then the return statement would make a copy, and the copy WOULD be destructed (but not the original!) when the caller is done using the returned object, eg:
Object f() {
Object *p=new Object();
return *p; // <-- copy made here
}
f(); // <-- ~Object() for the return value
// is called when the ';' is reached
In case #3, again the objects being created in dynamic memory are NOT destructed automatically upon return.
In all three cases, you can use std::unique_ptr to provide automatic memory management of dynamic objects, eg:
int f() {
std::unique_ptr<Object> p(new Object);
int something=5;
return something;
} // <-- ~unique_ptr() is called here
std::unique_ptr<Object> f() {
std::unique_ptr<Object> p(new Object);
return std::move(p);
} // <-- ~unique_ptr() for p is called here
f(); // <-- ~unique_ptr() for the return value
// is called when the ';' is reached
int f() {
for(int i=0; i<10; i++) {
std::unique_ptr<Object> p(new Object);
} // <-- ~unique_ptr() is called here
int something=5;
return something;
}
Absolutely not. C++ is not garbage-collected like Java.
Every new has to be balanced with a delete, and you need to pass the pointer you get back from new to that call to delete. (More formally that pointer has to be the same type too, or polymorphically related).
Fortunately, C++ does provide smart pointer classes like std::unique_ptr that wrap the delete call in its destructor.
I have the following code and I think that the arr property should be allocated on the heap, because the test object is allocated on the heap.
But for some reason, the A destructor is being called, even though I do not call it explicitly. Is there explanation for this?
CODE:
class A {
public: ~A(){
cout<< "detor A"<< endl;
}
};
class C {
A arr[10];
public: ~C(){
// delete[]arr;
}
};
int main() {
C* test = new C();
delete test;
}
OUTPUT:
detor A
detor A
.
.
The destructor of an object is called when the object has to be destroyed and independently of the way the object was allocated.
For example:
a local object is destroyed automatically when it goes out of scope
an object allocated with new is destroyed with delete
a member object is destroyed in the destruction process of its enclosing object
The last cases causes the behavior that you observe: you delete test, which requires arr to be destroyed, which requires each of its items to be destroyed.
`
class A{
public:
int x;
A* p;
};
int main(){
A obj1 = new A(); //no suitable constructor exists to convert from "A *" to "A"
A *obj2 = new A(); //Works fine
return 0;
}
`
Why is an object of class A declared as a pointer to that class, by default?
In other words, why does obj1 doesn't work but *obj2 does.
The new operator returns a pointer, so you can assign it only to a variable of pointer type.
You can use A obj1 = A();, which will simply call the constructor (without allocating dynamic memory, which is what new does) and return a A, not a A*.
No. Why is an object of class A declared as a pointer to that class, by default? Is incorrect. An object of class is just an object of that type and no pointer there.
The keyword new is used to allocate dynamic memory for a pointer. That is a memory must be cleaned up manually when you're done with it otherwise you will face a memory leak.
A* pObj = new A; // ok
A obj = new A; // error
A obj = *pObj; // ok:
Above obj is just an instance of class A and pObj is a pointer to an object of class A so inside the pointer there's the address of the object so to access it we dereference the pointer:
obj = *pObj = 0; // De-referencing pObj and assigning the value it points to to obj.
Finally clean up:
delete pObj; // ok
delete obj; // error
I am not sure what is wrong with this (keep in mind I'm kinda sorta new to C++)
I have this class:
Foo
{
string name;
public:
SetName(string);
}
string Foo::SetName(string name)
{
this->name = name;
return this->name;
};
//////////////////////////////////////////////
//This is where I am trying to return a Foo pointer from this global function:
Foo * ReturnFooPointer()
{
Foo foo;
Foo * foo_ptr;
foo_ptr = &foo;
return foo_ptr;
}
At compile time, this compiles just fine. However at run time it throws a runtime exception(Some sort of access violation)
What am I doing wrong?
You need to use the new keyword instead to create new Foo on the heap.
The object on the stack will be freed when the function ends, so you are returning a pointer to an invalid place in memory.
Here is the correct code.
Foo * ReturnFooPointer()
{
Foo * foo_ptr = new Foo();
return foo_ptr;
}
Remember later to delete the pointer you are returning.
So later in code:
Foo *pFoo = ReturnFooPointer();
//Use pFoo
//...
delete pFoo;
You're returning a pointer to a local object on the stack. It goes out of scope the moment your function returns, and is invalid.
You should create a new instance to return, i.e.,
Foo* foo_ptr = new Foo();
This will create an object in the heap and will live until you call delete on it.
the actual object is allocated on the stack so it is destroyed when it goes out of scope (when the function returns). If you allocate it on the heap (with new), it will be alive until you delete it