问一个关于“野指针”、“生命周期”的问题

percepto 2014-08-20 05:32:48
class A
{
 public:
  void Func(void){ cout << “Func of class A” << endl; }
};
void Test(void)
{
 A *p;
 if( true ) {
  A a;
  p = &a; // a 的生命期 ?
 }
 p->Func();
}


问题是a 的生命期不是结束了 ,然后p变成野指针

为什么 结果还会显示“Func of class A”

我的编译器是VC10
...全文
222 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2014-09-03
  • 打赏
  • 举报
回复
除非编译检查特别严格,这个程序逻辑虽然错误 代码不论编译,还是跑起来,都没有太多问题 因为 1)这个函数代码,没有用到 *p ,即 *this; 2)这个函数func不是虚函数 3) 这个类A的构造函数和析构函数什么也不做 这么多巧合,让这段代码不出错,正常运行。 PS: 但是这么写代码,没法保证程序,能够始终正常运行。 这是不足为训,它只是这这么多巧合之下,才勉强没出问题的。 C++并不保证,逻辑错误,以及不很合理的代码,一定不能正确运行。 编译器也不保证,一定会给出出错,或者警告信息。
percepto 2014-08-21
  • 打赏
  • 举报
回复
感谢大家的回答,认真的看了各楼的回复总结了一下: 1、 内存中的数据不会被销毁 只会被覆盖 2、 程序中的对象生命期虽然结束了,但是参照1 数据还没有被覆盖掉,指针指向的位置也没有变,所以还可以运行 3、这样做很危险。原因:指针指向的空间已经归还给系统,指向其进行操作会带来未知的结果
缤纷冷泪 2014-08-21
  • 打赏
  • 举报
回复
我个人理解 C++,将类的成员函数,在编译时,先改写成带类参数的C的函数 例如, class A { public: void func(){} }; void A::func() {} 被改写成 void func( A *this ) {}
引用 10 楼 holdsky 的回复:
#include <iostream>

class A
{
public:
    void Func(void)
    {
        std::cout<<"Func of class A"<<std::endl;
    }
};

int main(void)
{
    A *p = 0;
    p->Func();
    return 0;
}
楼主运行这段代码试试,我这运行正常
我个人理解 C++,将类的成员函数,在编译时,等价于带类指针的C的函数 例如, class A { public: void func( int number){ } }; void A::func() {} 被编译成等价函数 void func( A *this , int number ) {}
缤纷冷泪 2014-08-21
  • 打赏
  • 举报
回复
#include <iostream>

class A
{
public:
    void Func(void)
    {
        std::cout<<"Func of class A"<<std::endl;
    }
};

int main(void)
{
    A *p = 0;
    p->Func();
    return 0;
}
楼主运行这段代码试试,我这运行正常
qianfoyuan 2014-08-21
  • 打赏
  • 举报
回复
p = &a; 对象是在栈上静态分配的, 不是在堆上动态分配的(即new出来的), 在栈上的数据系统会自动回收不需要显示delete, 所以p不属于野指针.
风行踩火轮 2014-08-21
  • 打赏
  • 举报
回复
P是变成了野指针,但是地址还是客观存在的
zxg2063 2014-08-21
  • 打赏
  • 举报
回复
a 的生命期结束了 ,p变成野指针--这个是正确的 不过这仅仅代表a的内存可以被系统分配给其他对象,而不是清除了那块内存的数据。 只要没有被其他对象使用,还是可以按原来实现运行的,不过很危险罢了。
反转灵魂 2014-08-21
  • 打赏
  • 举报
回复
野指针 也是指针。 人死了遗产还有,遗体还在,除非被别人拿走了。
我看你有戏 2014-08-21
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;

class A
{
public:	
	A()
	{		
		cout<<"A()"<<endl;
	}
	~A()
	{
        cout<<"~A()"<<endl;
	}
	void Func(void)
	{ 
		cout <<"Func of class A" << endl; 
		//cout<<m_n<<endl;
	}
};
void Test(void)
{
	A *p;
// 	if( true ) {
// 		A a;
// 		p = &a; //  a 的生命期 ?
// 	}
	p->Func(); 

	int cc = 0;
	A *p1;
	p1= (A*)&cc;

	p1->Func();
}

int main()
{
	Test();
	system("pause");
	return 0;
}

这样也可以,vs2003.net环境下面测了下
IceNature 2014-08-20
  • 打赏
  • 举报
回复
p->Func()时对象还没来得及被销毁,所以还会有正确输出
unituniverse2 2014-08-20
  • 打赏
  • 举报
回复
引用 1 楼 percepto 的回复:
a 不是应该在 栈 中 然后栈中的数据 除了生命周期 会自动销毁么?
标准对这类代码应当具有的行为规定是“未定义”。 现实中,你觉得应当怎样执行才算合理??
赵4老师 2014-08-20
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。
percepto 2014-08-20
  • 打赏
  • 举报
回复
a 不是应该在 栈 中 然后栈中的数据 除了生命周期 会自动销毁么?

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧