为什么我可以访问已删除但在 C++ 中具有虚拟析构函数的对象?
Why can I access object that was deleted but had virtual destructor in C++?
我用 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;
}
并且 MyItem
中没有 virtual ~MyuItem()
class 我得到了预期的输出:
10 <- myVar before deconstructor
0 <- memory garbage
28802064
28802096
但是当我将代码更改为:
virtual ~MyItem(){
}
输出看起来不同:
10
10
10
10
为什么我仍然可以从不应指向包含数据的内存的实例中访问解引用值?我不明白虚拟析构函数如何影响它。或者还有其他我找不到的错误。我是不是少了什么?
是的,我想在我的容器 class 析构函数中删除它。只是因为我想了解它是如何在原始指针上工作的。我知道我应该使用智能指针,因为它们会自动释放内存。
访问已删除的对象是未定义的行为,没有说库必须清除内存,可以也可以不。你正在做的事情是你不能指望工作的事情,尽管它恰好在这种情况下发生。
我用 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;
}
并且 MyItem
中没有 virtual ~MyuItem()
class 我得到了预期的输出:
10 <- myVar before deconstructor
0 <- memory garbage
28802064
28802096
但是当我将代码更改为:
virtual ~MyItem(){
}
输出看起来不同:
10
10
10
10
为什么我仍然可以从不应指向包含数据的内存的实例中访问解引用值?我不明白虚拟析构函数如何影响它。或者还有其他我找不到的错误。我是不是少了什么?
是的,我想在我的容器 class 析构函数中删除它。只是因为我想了解它是如何在原始指针上工作的。我知道我应该使用智能指针,因为它们会自动释放内存。
访问已删除的对象是未定义的行为,没有说库必须清除内存,可以也可以不。你正在做的事情是你不能指望工作的事情,尽管它恰好在这种情况下发生。