I created simple code with 2 classes.
#include <list>
#include <iostream>
using namespace std;
class MyItem {
public:
int myVar;
MyItem() {
this->myVar = 10;
}
~MyItem(){
}
};
class Container {
public:
list<MyItem*> items;
Container() {
}
~Container(){
for (auto *item: this->items) {
delete item;
}
}
void addItems(MyItem* item) {
this->items.push_back(item);
}
};
int main() {
MyItem* i1 = new MyItem();
MyItem* i2 = new MyItem();
MyItem* i3 = new MyItem();
cout << i1->myVar << endl;
Container* c1 = new Container();
c1->addItems(i1);
c1->addItems(i2);
c1->addItems(i3);
delete c1;
cout << i1->myVar << endl;
cout << i2->myVar << endl;
cout << i3->myVar << endl;
}
And without virtual ~MyuItem()
in MyItem
class I get output as expected:
10 <- myVar before deconstructor
0 <- memory garbage
28802064
28802096
But when I change code to:
virtual ~MyItem(){
}
The output looks different:
10
10
10
10
Why I can still access dereference values from instances that should not point to memory with data? I don't understand how virtual destructor can affect it. Or there is other mistake that I cannot find. Am I something missing?
And yes I want to delete it in my container class destructor. Just because I want to understand how it works on raw pointers. I know that I should use smart pointers because they will automatically deallocate memory.
Accessing a deleted object is undefined behavior, nothing says that the library has to clear the memory, it can or it may not. What you are doing is something you can not count on working despite the fact that it happens to in this instance.