问题的场景:
先new一个对象p,假设对象里会执行到一个回调函数,如果在此回调函数里delete p,再继续执行代码;结果会怎么样?
可能结果:
1.对象已经被释放,this指针指向的一块无效的内存,那么继续执行this的成员函数或者其他的成员变量,应该会崩溃;
2.执行后面的代码,虽然内存已经访问非法,但是内存其实是可用的,或者叫做强行可用的,还可以继续执行,但是会有重新被分配出去,被其他线程修改引发的不可预期的行为;
测试的代码:
#include <stdio.h>
#include <stdlib.h>
typedef void (* PFUNC)(void*p,int a) ;
class Student;
class Node
{
public:
int a;
int b;
};
class Student
{
public:
Student()
{
a=11;
b=22;
c=33;
n=NULL;
printf("create:%p\n",this);
}
~Student()
{
printf("close:%p\n",this);
b=222;
c=333;
}
void test()
{
n=new Node();
n->a=1;
//n->b=2;
//c=55;
printf("test()_1:%p->a:%lld b:%lld c:%lld p:%p\n",this,a,b,c,n);
//pf(this,11);
printf("test()_2:%p->a:%lld b:%lld c:%lld p:%p\n",this,a,b,c,n);
test2();
}
void test2()
{
//printf("test2():%p->%d %d %p %d\n",this,a,b,n,c);
printf("test2():%p->%p %d\n",this,n,n->a);
}
Node* n;
long long a;
long long b;
long long c;
PFUNC pf;
//Node* n;
//int c;
};
void func(void* p,int a)
{
printf("func %d\n",a);
Student* p1=(Student*)p;
delete p1;
}
int main()
{
Student* p = new Student();
p->pf=func;
p->test();
printf("--\n");
//delete p;
// delete p;
//p->test();
return 0;
}
测试步骤与运行结果:
1.
Student*p=new Student();
delete p;
delete p;
重复释放会崩溃;
2.
Student*p=new Student();
delete p;
p->test()程序可以运行成功;
但是这样做的风险在于:p指向的内存会被其他线程分配得到,于是出现不可预期的错误;
delete p之后会把p指向的地址起始的8字节置为0,假如头8字节是一个指针,程序立即就会崩溃;
引申阅读:
http://blog.csdn.net/passion_wu128/article/details/38966581 C++new和delete实现原理