在执行语句
delete p;
后,p所指向的内存已经被释放,该指针变成dangling pointer,即悬垂指针。悬垂指针指向曾经存放对象的内存,但该对象已经不存在了。悬垂指针往往导致程序错误,而且很难检测出来。
悬垂指针往往在你使用一个生命周期已经结束的对象的地址时产生。
class Sample { public: int *ptr; Sample(int i) { ptr = new int(i); } ~Sample() { delete ptr; } void PrintVal() { cout << "The value is " << *ptr; } }; void SomeFunc(Sample x) { cout << "Say i am in someFunc " << endl; } int main() { Sample s1 = 10; //此处先创建一个int型的临时变量,再调用构造函数sample(int i)初始化成员变量。 SomeFunc(s1); //调用系统自动合成的复制构造函数将s1副本传递给形参sample x,此时两对象的ptr成员将指向同一个内存空间。 s1.PrintVal(); //此时局部变量Sample x离开作用域,自动调用显示定义的析构函数,ptr指向的内存区域被回收。ptr 称为悬垂指针,试图通过s1打印*ptr。出错!!!! }
注意点:当对象的引用或指针超出作用域时,不会运行析构函数。只有删除指向动态分配对象的指针或实际对象(而不是对象的引用)超出作用域时,才会运行析构函数。