使用Delete 一个指针后,如何在析构函数中把该指针的值设置为NULL ??

xwhjd760626 2009-01-25 11:35:00
使用Delete 一个指针后,如何在析构函数中把该指针的值设置为NULL ??

比如我创建一个类为A

A *p=new A;
delete p;
后自动调用析构函数,我想在析构函数中设置.
...全文
568 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
VCACC 2011-10-19
  • 打赏
  • 举报
回复
学习了。
vempheng 2011-10-19
  • 打赏
  • 举报
回复
受教了
  • 打赏
  • 举报
回复
晕了,没搞明白!
foxingy 2011-07-14
  • 打赏
  • 举报
回复
编译器 name-mangling:
p->name();
编译成类似:Demo_vname(p);
就跟普通非成员函数功能一样。
只要name()函数体里没有用到类成员p->m_i,就跟静态方法一样用。。。
shenjigong19801109 2009-02-01
  • 打赏
  • 举报
回复
上面语句有错,哈。


//////////////////////////////////////////////////////////////////////
1、因为p申明为一个类型的指针。因此可以调用此类型的所有可调用的函数和数据(条件是:指针指向的是
此数据在内存中的地址)。
2、指针p虽然赋值为空值,但它是依然是此类型的指针,因此根据1的回答是可以调用此类型所包含的函数
(条件是:被调用函数中不包括数据成员,如果被置空的指针调用数据成员或包含数据成员的函数将会出错。
原因是:指针已不是指向数据成员的地址)。
如果你还是不能理解,可以与我交流/C++爱好都QQ:927902301
shenjigong19801109 2009-02-01
  • 打赏
  • 举报
回复
1、因为p申明为一个类型的指针。因此可以调用此类型的所有可调用的函数和数据(条件是指针指向的是
此数据在内在内存中的地址)。
2、指针p虽然赋值为空值,但它是依然是此类型的指针,因此根据1的回答是可以调用此类型所包含的函数
(条件是被调用函数中不包括数据成员,如果被置空的指针调用数据成员或包含数据成员的函数将会出错。
原因是:指针已不是指向数据成员的地址)。
如果你还是不能理解,可以与我交流/C++爱好都QQ:927902301
passionboy03 2009-02-01
  • 打赏
  • 举报
回复
不会吧。这里的P这个指针还存在么,我去试验一下。

10分钟后。。。。

结果不仅这个P还在,就算把它赋值成NULL,还可以调用。不知道怎么回事了。。

C/C++ code
#include<iostream>
using namespace std;
class Demo
{
public:
void name()
{
cout << "hello,world" << endl;
};
};

class Demo1{};


int main(int argc, char** argv)
{
Demo* p = new Demo;//hello world 应该是在这儿输出的,因为在构造类的时候成员函数void name ()缺省
// {
// cout << "hello,world" << endl;
// };

delete p;
p = NULL;//
p->name();//而不是在这儿输出的hello world,清零后,再次调用不会出错,只是指向的内存为空,所以输
//出是构造时输出的
return 0;
}




结果是输出hello world,请高手解释!!!!!!!!!!!
deng2000 2009-01-30
  • 打赏
  • 举报
回复
很是抱歉,现在才发现我在27楼的程序有个漏洞:析构函数固然把指针p置零了,可其后释放内存时operator delete所得到的参数值也是NULL了,因此A所占内存没被释放,即有内存泄漏。

改进方法很简单,重载A的operator delete,把之前A析构函数中的内容转移到其中就ok了。程序如下:

#include <iostream>
using namespace std;

class A
{
public:
void operator delete(void *);
int a;
};

void A::operator delete(void *p)
{
free(p);

int n;
int *pr = &n;
int me = (int)p;
for (int i=0; i<500; i++)
{
if (pr[i]==me)
{
pr[i] = 0;
}
}

cout << "operator delete" << endl;
}


int main()
{
A *p = new A;
delete p;

cout << "p=" << (int)p << endl;
return 0;
}

hemiya 2009-01-30
  • 打赏
  • 举报
回复
最近搞个东西遇到和楼主差不多的问题.
我是在类的内部声明一个指针的指针.

class A
{
public:
A **point;
~A(){ *point = NULL;}
};

A *p=new A;
p->point = &p;
delete p;
deng2000 2009-01-30
  • 打赏
  • 举报
回复
凑个热闹,楼主的问题很难找到完美的解决方法。其实从另外一个角度看,这种要求有点”过分“,因为指向A的指针完全可能是个常量:
const A* p = new A;
这种情况下改变p的值会导致错误.

因此,只可能在有局限性的前提下解决楼主的问题。25楼的方法很不错,只是把程序中所有delete全部用DELETE代替(还需把参数括起来)代价有点大。btw, 25楼的程序似乎有一个笔误:#define折行的话需在行末加 "\"

我想到一个丑陋的解法是扫描桟,找到所有等于p的值将其致零。程序如下:

#include <iostream>
using namespace std;

class A
{
public:
~A();
int a;
};

A::~A()
{
cout << "A destructor" << endl;
int n;
int *pr = &n;
int me = (int)this;
for (int i=0; i<500; i++)
{
if (pr[i]==me)
{
pr[i] = 0;
}
}
}

int main()
{
A *p = new A;
delete p;

cout << "p=" << (int)p << endl;
return 0;
}



在VS2003中,运行结果是

A destructor
p=0

此方法优点是对程序的改动量小,但它有很大的安全性问题,象这样操作桟的方式是很危险的。

tangshuiling 2009-01-30
  • 打赏
  • 举报
回复

c/c++就是这种类型决定行为的语法,否则,微软也不会在他的MFC类库中来个运行时类型识别RTTI的封装啦
arong1234 2009-01-30
  • 打赏
  • 举报
回复
最简单的做法是:
所有delete全部用DELETE代替
然后全局定义

#define mydelete delete
#define DELETE(p) do {
mydelete p;
p=NULL;
}while(0)




brookmill 2009-01-29
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 Great_Bug 的回复:]
哇卡卡~~~从楼主的问题扯过来~~~~扯远哩
[/Quote]
是有点扯远了……
楼主的问题,好象没什么办法做到啊
Great_Bug 2009-01-29
  • 打赏
  • 举报
回复
哇卡卡~~~从楼主的问题扯过来~~~~扯远哩
Wolf0403 2009-01-28
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 iambic 的回复:]
有些人总是过分担心不应该存在的代码。
[/Quote]

同意。
在研究一个问题的技术实现之前应该判断这个问题本身是不是有意义的问题。
Guilty 2009-01-28
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 joshua0137 的回复:]
这不是常规做法吧
[/Quote]
这是很现实的问题,搞不懂这个问题的人,迟早要在this指针上出毛病。
不过我承认很多C++程序员从来就没有彻底理解this指针,凑合过吧.
iambic 2009-01-28
  • 打赏
  • 举报
回复
有些人总是过分担心不应该存在的代码。
捕鲸叉 2009-01-28
  • 打赏
  • 举报
回复
这不是常规做法吧
brookmill 2009-01-27
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sese53 的回复:]
你们写的是什么,很不懂
[/Quote]
不懂也没关系,这个有点钻牛角尖了。

((Demo*)NULL)->name();
这是说把0强制转换成Demo类型的指针,然后调用其成员函数,
和Demo* p = NULL; p->name(); 的效果是一样的。

再多罗嗦几句:
如果有这样一段C++代码
class Demo
{
public:
int m_i;
void name()
{
cout << m_i << endl;
}
};

int main(int argc, char** argv)
{
Demo* p = new Demo;
p->name();

编译器会把它转化成类似这样的C代码:
struct Demo
{
int m_i;
};

void name__4Demo(struct Demo *p)
{
cout << p->m_i << endl;
}

int main(int argc, char** argv)
{
Demo* p = new Demo;
name__4Demo(p);

这个例子里,函数name访问了成员变量,所以如5楼所说,如果p是NULL就会出问题。
而如果name不访问成员变量,也就是不使用p指针,那么即使p是NULL也没关系
icesky_ff 2009-01-27
  • 打赏
  • 举报
回复
学习……
加载更多回复(14)

64,670

社区成员

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

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