#include <iostream.h>class A
{
public: void Func(void)
{
cout << "Func of class A" << endl;
}};
void Test(void)
{
A *p; {
A a; p = &a; // 注意 a 的生命期 } p->Func(); // p是"野指针"
}
void main( void )
{
Test();
}
{
public: void Func(void)
{
cout << "Func of class A" << endl;
}};
void Test(void)
{
A *p; {
A a; p = &a; // 注意 a 的生命期 } p->Func(); // p是"野指针"
}
void main( void )
{
Test();
}
{
A *p=NULL; {
A a; //p = &a;
} p->Func(); // p是"野指针"
}这样也可出结果
A a;
p=&a;
}
这个代码块和:
p=new A;
是完全一样的。所以应该就是输入正确答案吧。
A a;
p=&a;
delete a;
}
这样P才是野指针
p->Func(); // p是"野指针"
时,a虽然是死了,但p还是没有死呀.
除非你在此之前 delete p; 那就到
p->Func(); // p是"野指针"
这一行时就会出错了
A里加个成员试试
class A
{
char buf[128];
public: void Func(void)
{
strcpy(buf,"test");
cout << "Func of class A" <<buf<< endl;
}};
____________________p->Func()好比调用了
A::Func();
{
A a; p = &a; // 注意 a 的生命期}
這段是在花括號裡面的.理論上走出去以後a就消失了.但是在vc裡面,a地址仍然存在.這不能說是編譯器bug.但是這是編譯器的運行機制造成的.
{
A *p; {
A a; p = &a; // 注意 a 的生命期 } p->Func(); // p是"野指针"
}
这段代码里,a的内存是分配于堆栈上的,即程序最初进入函数时使用
push ebp
mov ebp,esp
sub esp,(size)
的方法来形成a的内存,然后调用A的构造函数对a进行初始化,而p也是堆栈变量,所以p=&a;的意思不过是把p的地址赋成堆栈的另一个地址,所以p当然会始终有效编译器控制的只是程序调用的方法,例如把上述代码改成:
void Test(void)
{
A *p; {
A a; p = &a; // 注意 a 的生命期 } a.Func();
//p->Func(); // p是"野指针"
}
则肯定会编译不通过,所以生命周期只是针对调用该对象的使用范围,超出范围会调用对象的析构函数,但是释放内存和生命周期无太直接的联系!
因为已经有指针指向那快内存了。
----------------------------------------
呵呵,C++还没有这么智能吧。
A* p;
p->func();
也是不会错的,因为非virtual成员函数的调用是早捆绑,也即编译时就决定了调用地址,而函数里又没有对成员变量的引用,所以“幸运的存活”下来了。
A* p = NULL;
p->Func();
也照样可以运行我的帖子里也有过这样的讨论
http://community.csdn.net/Expert/topic/2878/2878307.xml?temp=.6796839