为什么这个程序不报错呀(new和delete内存释放问题)

HAN-Kai 2012-10-09 02:57:32
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"Base"<<endl;
}
void Disp()
{
cout<<"display"<<endl;
}
};

Base* f()
{
Base *pBase= new Base();
delete pBase;//在这句后面加上pBase = NULL;也能正常运行。
return pBase;
}
int main()
{
Base* a=f();
a->Disp();
return 0;
}

为什么这个程序能正常运行呢?已经delete了,就不应该返回正确的地址了呀,而且就算我在delete后面加上pBase=NULL;也还能正确返回,这是为什么呢?求教。
...全文
283 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
kakaximodo 2012-10-09
  • 打赏
  • 举报
回复
最基础的知识是最没有,也是最有用的
5t4rk 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

“new”和“delete”
不对应
“生”和“死”
对应
“借”和“还”。
[/Quote]

精辟+++
Xomic 2012-10-09
  • 打赏
  • 举报
回复
delete 说明这个指针所指的内存可以被程序其他代码改写,不delete说明这个指针一直占有这块内存别人不准用!

当delete了,但是没有其他地方使用这块内存,这块内存的值依然不变

(计算机里面的删除其实是覆盖掉了原来的值)

这样应该够通俗了吧!
赵4老师 2012-10-09
  • 打赏
  • 举报
回复
“new”和“delete”
不对应
“生”和“死”
对应
“借”和“还”。
HAN-Kai 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

baichi4141,

“要么严格按照标准规定的语法写程序不越雷池一步,要么系统学习汇编语言和编译原理。”

这一点很赞同,其实踏实深入的学习一下是非常好的,学习C++是漫长的过程。切忌浮躁:)

generalhking,

理论其实非常简单,没有很难得东西,关键是你能不能找到这些理论并记住它。
[/Quote]嗯,呵呵,高手总是心态比较正。学习了。多谢指教。
popy007 2012-10-09
  • 打赏
  • 举报
回复
baichi4141,

“要么严格按照标准规定的语法写程序不越雷池一步,要么系统学习汇编语言和编译原理。”

这一点很赞同,其实踏实深入的学习一下是非常好的,学习C++是漫长的过程。切忌浮躁:)

generalhking,

理论其实非常简单,没有很难得东西,关键是你能不能找到这些理论并记住它。
HAN-Kai 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

编译器只能检查出语法错误
没语法错误就能编译通过
但是 这不代表代码没问题
你的代码就是典型了
还可以据几个例子
C/C++ code

int arr[10];
arr[10]=15;//明显的数组越界 不过不一定会出问题 能"正常运行"也不是没见过


或者
C/C++ code

int i;
scanf("%d", &i);/……
[/Quote]多谢指教。
HAN-Kai 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

C++中,一个类的function有三种:

nonstatic
static
virtual

前两者在内部模型中拥有完全独立的地址。我们对一个A class object进行调用

a.f()
pa->f()

实际上,在compile-time被转换成

___A_@xxf( &a );
___A_@xxf( pa );

这样的形式。上面的函数名被……
[/Quote]多谢兄台指教,我在Disp()中加了this后进行实验果然发现的不同。
baichi4141 2012-10-09
  • 打赏
  • 举报
回复
顺便,其实3楼的解答就是能够运行正常的本质原因,但楼主直接视而不见。
为什么呢?基础知识不够,根本听不懂3楼在说些什么。

所以说,别想了,也别问了,这种行为一点意义都没有。
要么严格按照标准规定的语法写程序不越雷池一步,要么系统学习汇编语言和编译原理。
baichi4141 2012-10-09
  • 打赏
  • 举报
回复
这个问题需要楼主懂得基本的汇编语言才能解答明白

简单地说,你拥有一栋楼位于北纬30度东经22度的地点内,当你不想再使用这栋楼的时候你把它炸了——请问,你的行为会不会导致“北纬30度东经22度”这个地点无效?
地址地址,顾名思义,就是位置,你可以把一个位置上的东西砸坏,你可以宣布这个位置属于你或者不属于你,但你能够宣布“这个位置不存在”吗?
唯一能做到这点的方法,就是拿起锤子砸坏内存条。

至于运行正常,就更复杂一点了,简单地说,你调用的函数跟具体的对象没有关系,无论指针指向哪里,这个函数都能正确输出。

更加详细本质准确的解答,楼主自己去查编译原理等等汇编层面的东西吧。
一句话,别自己空想了,你自己空想的理解,可能有些是对的,但大多数一般是没谱的。
HAN-Kai 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

delete只是释放掉了该地址的内存,地址依然存在,可以返回该地址,但是不能访问该地址指向的内容,不过这也是运行时才会报错,编译依然会通过、、、
[/Quote]运行也正常啊。
mujiok2003 2012-10-09
  • 打赏
  • 举报
回复

a->Disp(); // 函数内部没有访问a/this


所以没AV。不过这次没有问题,下次就未必了。
lin5161678 2012-10-09
  • 打赏
  • 举报
回复
编译器只能检查出语法错误
没语法错误就能编译通过
但是 这不代表代码没问题
你的代码就是典型了
还可以据几个例子

int arr[10];
arr[10]=15;//明显的数组越界 不过不一定会出问题 能"正常运行"也不是没见过

或者

int i;
scanf("%d", &i);//输入3 8 1 4 9....都能得到正确答案 但是如果输入0 那么.......
printf("%lf", 1.0/i);
popy007 2012-10-09
  • 打赏
  • 举报
回复
C++中,一个类的function有三种:

nonstatic
static
virtual

前两者在内部模型中拥有完全独立的地址。我们对一个A class object进行调用

a.f()
pa->f()

实际上,在compile-time被转换成

___A_@xxf( &a );
___A_@xxf( pa );

这样的形式。上面的函数名被compiler进行了name mangling处理(每个编译器的取名方式不同),脱离了C++的类外衣,变成了纯C的表达。传入的就是对于类概念来说的this指针。如果两个函数中没有用到这个this,&a和pa在内部就会被忽略——就算是传入了NULL或者非法值,也没关系。

同理,

a->Disp()

会变成类似__Base_@xxDisp( a )

这样的形式,这个方法,因为没有访问成员变量,也就忽略了this指针。这导致了看似不正确的调用却安然无恙。

在C++standard引入static member function之前,对于static data member的访问,很多程序员喜欢用

( (A*) 0 )->f();

这样的形式——就是基于这个原因。
碎碎念 2012-10-09
  • 打赏
  • 举报
回复
delete只是释放掉了该地址的内存,地址依然存在,可以返回该地址,但是不能访问该地址指向的内容,不过这也是运行时才会报错,编译依然会通过、、、
HAN-Kai 2012-10-09
  • 打赏
  • 举报
回复
本人在dev c++和vc6.0下面实验,均能通过编译,正常运行。没有报错。

64,646

社区成员

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

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