[c++]delete对象指针后,释放了该对象的内存,但是为什么指针还能访问该对象?

老A的AI实验室 2016-11-07 09:11:44
delete对象指针后,释放了该对象的内存,但是为什么指针还能访问该对象?
是不是都要在delete p;后加上p = NULL?

#include <iostream>

using namespace std;

class Box
{
public:
Box(int,int);
~Box();
void volume();
static int height;
int width;
int length;
};
Box::Box(int wi, int le)
{
width = wi;
length = le;
}
Box::~Box(){cout<<"the pointer is released."<<endl;}
void Box::volume()
{
cout<<height*width*length<<endl;
}
int Box::height = 100;

int main()
{
Box* p = new Box(10,20);
delete p;
cout<<p->height<<endl;
cout<<Box::height<<endl;
p->volume();
return 0;
}

输出如下:
the pointer is released.
100
100
20000
...全文
2832 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
老A的AI实验室 2016-11-10
  • 打赏
  • 举报
回复
引用 1 楼 fefe82 的回复:
访问 delete 之后的内存是一个未定义行为。 未定义行为可能产生任何结果,包括但不限于:产生期望的结果,产生未期望的结果,产生随机的结果,产生无法解释的结果,运行错误,随机的运行时错误,编译错误,等等 ====================================== 你只是放弃了对这片内存的所有权。获得所有权的人对这片内存做什么(或者说什么都不做)都不关你的事。
引用 1 楼 fefe82 的回复:
访问 delete 之后的内存是一个未定义行为。 未定义行为可能产生任何结果,包括但不限于:产生期望的结果,产生未期望的结果,产生随机的结果,产生无法解释的结果,运行错误,随机的运行时错误,编译错误,等等 ====================================== 你只是放弃了对这片内存的所有权。获得所有权的人对这片内存做什么(或者说什么都不做)都不关你的事。
阁下说的很清楚
Ouyang_Lianjun 2016-11-08
  • 打赏
  • 举报
回复
个人的见解: 指针的原理:当我们申请堆空间时,系统就会有一个标志来告诉我们,这些堆内存是没有人用的,给你用了。当你使用delete时,就是告诉系统那些堆内存我不用了,你拿去给别人用吧,这是时候,你之前写的东西还是在那里的,而且这个指针还是指向堆内存,而且那个堆内存里的东西,如果系统一直没用使用的话,它的值会一直存在。 所以为防止释放了堆内存的指针又再次去访问该堆内存,我一定要养好delete完,把该指针置空的习惯
赵4老师 2016-11-08
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
fefe82 2016-11-08
  • 打赏
  • 举报
回复
引用 8 楼 60 的回复:
告诉你一个技巧,如何不创建类的对象就能调用类得成员方法(不是类的静态方法哦)

class Box // 你的Box类
{
....
};

int main()
{
	int ii[10] = { 2, 3, 4, 5, 6,7 , 8, 9, 10 };

	void* p = &(ii[2]);
	((Box*)p)->volume(); // (1)调用成员方法,输出2000(猜猜2000是怎么出来的?)。

	p = NULL;
	((Box*)p)->volume(); // 2、调用成员方法。
	return 0;
}
当然了上述代码,执行时会有错误,但是编译时没有错误,而且是完全合法的。其中(1)执行成功,输出2000,(2)执行错误。执行错误是因为 NULL指向的地址是一块特殊的内存,运行环境和操作系统做了保护,如果p指向的是一块其它的内存,也有可能执行成功。 上述代码说明了一个问题,new、malloc只是声明一块内存是你的,你也可以不用声明,直接强制使用一块内存,只要你能预计可能的后果。 所以delete后的内存仍然是可以访问并操作的。
10 If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined: (10.1) — the dynamic type of the object, (10.2) — a cv-qualified version of the dynamic type of the object, (10.3) — a type similar (as defined in 4.4) to the dynamic type of the object, (10.4) — a type that is the signed or unsigned type corresponding to the dynamic type of the object, (10.5) — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object, (10.6) — an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union), (10.7) — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object, (10.8) — a char or unsigned char type.
begodliker 2016-11-07
  • 打赏
  • 举报
回复
你只是释放了指针所指向的内存,并没有删除这个指针。
AlbertS 2016-11-07
  • 打赏
  • 举报
回复
delete之后需要把指针置为NULL 如果不清空指针,继续访问会出现未定义的结果,如果那段内存未被重新使用,也许可以正常访问,如果已经重新分配给其他的程序,则结果可想而知
ArthurJava 2016-11-07
  • 打赏
  • 举报
回复
引用 2 楼 cherish_ff 的回复:
楼上回答的很清楚。
ESMGAL 2016-11-07
  • 打赏
  • 举报
回复
楼上回答的很清楚。
fefe82 2016-11-07
  • 打赏
  • 举报
回复
访问 delete 之后的内存是一个未定义行为。 未定义行为可能产生任何结果,包括但不限于:产生期望的结果,产生未期望的结果,产生随机的结果,产生无法解释的结果,运行错误,随机的运行时错误,编译错误,等等 ====================================== 你只是放弃了对这片内存的所有权。获得所有权的人对这片内存做什么(或者说什么都不做)都不关你的事。
encoderlee 版主 2016-11-07
  • 打赏
  • 举报
回复
你租了套房子,住了一段时间,到期归还房东后。
你仍然可以用事先配好的钥匙悄悄打开房门住进去,
刚开始没有新房客住进来,你觉得一切都很顺利,但随时都可能Boom!!!

所以,为了避免侥幸心理,要么把你配的钥匙销毁掉,以打消这种念头,要么当初就不该自己去配第二把钥匙,只需把原钥匙交还房东即可。
060 2016-11-07
  • 打赏
  • 举报
回复
告诉你一个技巧,如何不创建类的对象就能调用类得成员方法(不是类的静态方法哦)

class Box // 你的Box类
{
....
};

int main()
{
	int ii[10] = { 2, 3, 4, 5, 6,7 , 8, 9, 10 };

	void* p = &(ii[2]);
	((Box*)p)->volume(); // (1)调用成员方法,输出2000(猜猜2000是怎么出来的?)。

	p = NULL;
	((Box*)p)->volume(); // 2、调用成员方法。
	return 0;
}
当然了上述代码,执行时会有错误,但是编译时没有错误,而且是完全合法的。其中(1)执行成功,输出2000,(2)执行错误。执行错误是因为 NULL指向的地址是一块特殊的内存,运行环境和操作系统做了保护,如果p指向的是一块其它的内存,也有可能执行成功。 上述代码说明了一个问题,new、malloc只是声明一块内存是你的,你也可以不用声明,直接强制使用一块内存,只要你能预计可能的后果。 所以delete后的内存仍然是可以访问并操作的。
小灸舞 2016-11-07
  • 打赏
  • 举报
回复
你租用了政府的一块地(new),并在上面盖了个房子(初始化),并在里面住了一段时间,做了一些事情(使用)。 当你不需要了,你应该把地归还政府(delete)。政府这时只是登记一下,某地块现在已经空闲了,它并不会去清除那块地上的房子,但政府随时可能把地提供给其它申请者,虽然房子可能还没拆,但如果你继续住在里面的话(访问已释放的内存),你随时都可能会在梦中被推土机碾成肉酱。
paschen 版主 2016-11-07
  • 打赏
  • 举报
回复
指针访问的只不过是那片内存,但你对象已经释放,访问是未定义行为,这块内存可能分配给其他的数据,你访问到的是不属于你的东西

64,654

社区成员

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

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