#include <iostream>
#include <cstring>
class Foo {
public:
uint32_t m_Size;
char *m_Data;
public:
Foo() = default;
Foo(const char *pieceOfString) {
printf("Foo Created!\n");
m_Size = strlen(pieceOfString);
m_Data = new char[m_Size];
memcpy(m_Data, pieceOfString, m_Size);
}
~Foo() {
printf("Deleted Foo. ");
delete[] this->m_Data;
}
};
class Entity {
public:
Foo m_Name;
public:
Entity(const Foo &name){
this->m_Name=name;
}
~Entity(){
printf("Deleted entity. ");
}
};
int main() {
Foo* apple=new Foo("something");
Entity entity=Entity(*apple);
return 0;
}
As the result of the code above, my console output was:
Foo Created!
Deleted Entity. Deleted Foo.
If a new object is created with the new
operator, delete
or delete[]
operator has to be used in order to free the corresponding memory blocks of the heap. In my example below, I had not used the delete
keyword to destruct Foo
object (which was created by new), however the destructors of the classes were executed properly. I suppose the automatic destruction of the entity
object involves calling the destruction of apple
as it is a member of entity
. But I am not sure about it.
If I write delete apple, it gives me free(): double free detected in tcache 2
.
Any help is appreciated!
Answer:
After making some research and reading the comments, I can answer my question: Why destructor is automatically called in case of new operator? The destructor is not automatically called in case of new operator. In the example there is a variable created on the stack called entity
. Because it goes out of scope, first its user-defined destructor is called. That is why Deleted Entity
is written on console. After that, it continues to destruct the members. There is only one with Foo type and Foo class has also got a user defined destructor. That is why Deleted Foo
appears on the output and the block on the heap pointed by entity.m_Name.m_Data
is freed up due to delete[] this->m_Data;
as it is also in the destructor. Because the apple object and the m_Name
member of the entity points to the same place, calling delete apple;
was indicating free(): double free detected in tcache 2
. So the user-defined destructors of Foo and Entity were called due to the stack allocated entity
was going out of scope.
However, this case must be avoided as the example violates the rule of three: The apple
object and the m_Name
member of the entity points to the same place.