#include <iostream>
using namespace std;
class A
{
public:
int a;
A()
{
a=2;
}
~A()
{
a=1;
}
};
int main()
{
A * aa = new A();
delete aa;
if (aa)
cout<< aa->a;
else
cout<<"123";
}
我创建了一个指向类实例的指针,我调用构造函数,变量“a”包含数字 2。我调用析构函数(其中这个“a”应该等于 1)。首先,我检查是否有指向该类实例的指针。原来,不仅在析构函数之后存在,数字0也位于“a”中,原来0开始位于内存中,但还是被程序占用了?如何从内存中删除一个类的整个实例?如果我用丢失的类替换对类的引用(在本例中为“aa”),那么(逻辑上)这不会释放内存,而只会允许我不再通过这个引用来管理这个内存。
(强调我的)
之后
delete aa;
,指针aa
变为无效,行为if (aa)
取决于编译器。更重要的是,下一行 -
aa->a
- 由于通过无效指针访问而导致未定义的行为。由于未定义行为,因此争论您在控制台
0
或其他内容中看到的原因几乎没有意义。delete
不会使指针无效。所以检查不起作用。他不存在”。该对象在调用析构函数1后不再存在。
但是语言中没有办法检查指针是否指向“现有”对象。
a
- 也不存在。从中读取是未定义的行为。“从记忆中删除”是什么意思?内存是字节的集合。您可以将对象所在的字节的值更改为其他一些,仅此而已。这些字节不能被“删除”。
1更准确地说,是一个重要的析构函数,但这在这里并不重要。
后
存储在变量中的指针的值
aa
不会改变。它指向一个已经释放的内存块,它可以保持在相同的状态,被覆盖 - 通常,任何事情都可能发生在它身上(这就是未定义行为的用途)。无论如何,你不应该联系他——这不会带来任何好处。
该程序具有未定义的行为,因为在删除类对象后
指针值
aa
变得无效。也就是说,指针不指向程序中现有的“活动”对象。请记住,调用函数运算符
delete
或delete[]
不会更改指针的值。由于指针是按值传递给函数运算符的,也就是说,函数运算符处理的是原始指针值的副本。这意味着签入
if-предложении
将给出真实的也就是说,
aa
它不是null-указатель
但是,访问不再存在的对象的成员
导致未定义的行为。
我们把程序放大一点,这样会更清楚:
程序:
编译器不知道程序员想要对分配的内存做什么(或不想做什么)。因此,
не нужно
如上所述проверить, указывает указатель на "существующий" объект, или нет, не только потому что нет в языке такого способа.