为什么这没有问题
下面的代码在vc6和vc.net中都能编译运行,没有问题
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
using namespace std;
class A
{
public:
void prt(void){cout < < "hello " < <endl;}
};
int main()
{
A *p;
{
A a;
p=&a;
}
p-> prt();
return 0;
}
[解决办法]
析构了也没有关系,因为没访问到非法的内存。你改下就可能会出错了:
class A
{
int i;
public:
void prt(void){ i = 0; }
};
[解决办法]
应该是这样的吧
虽然
{
A a;
p = &a;
}
当a出了作用域之后,的确会在右花括号那里退栈,但是只是sp移动了,并没有把这个p指向的这个地址的内容清除掉(其实这个时候指针p是在非法访问),而后面的p-〉f()最后是变成f(this),由于这个地方的内容并没有清除掉,即this仍然有效,所以仍然可以执行
[解决办法]
恩,在析构函数调用以后再访问成员变量的行为是 Undefined。
所以林锐博士的做法和iambic的做法是有本质区别的。
不过 Undefined 是依赖于编译器的。因为如LS所说,一个block的退栈可以是只是移动了栈顶指针。因此,为了鲜明地反映这个问题,使用以下的class A
class A
{
private:
int* i;
public:
A() : i(new int(0)) {}
~A() { delete i; }
void prt(void){ cout < < *i < <endl;}
};
使用这个class A,在VS2005上 ptr()打印出一个大负数,在g++(Dev-cpp)中,仍然显示0.