C++中的delete的机制是怎样的呢?

clever101
博客专家认证
2006-12-21 11:46:28
比如int *p = new int[100];
......
delete []p;

我觉得这种做法不太保险。比较保险的做法是
int *p = NULL; // 先进行初始化
p = new int[100];
......
if(NULL!=p) delete []p;

虽然这样写有点繁琐,但我认为是有道理的。因为不进行初始化,p的值是一个随机值,假如申请内存不成功,delete这一步肯定出错。但是我又想delete的机制的实质是怎样的呢?它能不能根据内存的所有权来判断是否收回内存呢?
...全文
748 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
axx1611 2006-12-24
  • 打赏
  • 举报
回复
没必要~~ 内存都没了 你再怎么补救都是无用的
clever101 2006-12-24
  • 打赏
  • 举报
回复
感谢诸位大虾,只是我有点不解。
假如在工作中,为开辟一片内存专门写一个异常有必要吗?比如下面

int* p = 0;

try
{
p = new int[100];
}
catch(bad_alloc& e)
{
...//处理异常
}
sopro 2006-12-22
  • 打赏
  • 举报
回复
--------
new失败也不是马上就抛异常,它先要检查有没有new_handler,如果用set_new_handler指定
了函数,就会去执行这个函数,如果没指定就抛出异常。
--------

你说的是operator new把,不是new,不一样的
sopro 2006-12-22
  • 打赏
  • 举报
回复
to cmail(寧采臣):
NULL是头文件里面定义的,有的编译器没有NULL定义,自己得定义一个
不如直接使用0



to 楼主:
更正我前面的代码,你可以这么弄:
int* p = 0;

try
{
p = new int[100];
}
catch(bad_alloc& e)
{
...//处理异常
}

delete[] p; //不再需要判断,即使是0指针,也不会有害:)

p = 0;
cmail 2006-12-22
  • 打赏
  • 举报
回复
new失败也不是马上就抛异常,它先要检查有没有new_handler,如果用set_new_handler指定
了函数,就会去执行这个函数,如果没指定就抛出异常。
ssafa 2006-12-22
  • 打赏
  • 举报
回复
不需要测试,delete自己会测试的
cmail 2006-12-22
  • 打赏
  • 举报
回复
to sopro(倾听世界)

用零为什么保险些?在C++ 里面NULL就是0这没错,但在C里里NULL是(void*)0
并不是0啊。用NULL不是可移植性好些?至少理解起来应该是这样。
___NULL 2006-12-22
  • 打赏
  • 举报
回复
char* buf = new char[100];
strcpy(buf, "Hello!");
printf("%s", buf);
delete buf;
buf = NULL;
axx1611 2006-12-22
  • 打赏
  • 举报
回复
C++规定了delete空指针不会做任何操作,是完全无害的
放心用吧
cmail 2006-12-22
  • 打赏
  • 举报
回复
if(NULL!=p) delete []p;
----------------
前面的测试完全多余。
delete内部会测试,delete空指针没任何破坏性,这样写就等于测试了两次。
sopro 2006-12-22
  • 打赏
  • 举报
回复
---
你写错了
---

不是写错了,是理解有些小问题:)
sopro 2006-12-22
  • 打赏
  • 举报
回复
你写错了

1. NULL不过是个宏定义而已,还是使用0代替保险一点

2. 正确的顺序是这样的:
int* p = 0;

try
{
p = new int[100];
}
catch(bad_alloc& e)
{
...//处理异常
}

if (p != 0) delete[] p; //如果抛过异常,那么p = 0,不执行这个语句

p = 0;

这里值得注意的是delete[] p;之后,p并不是NULL(0)的,必须人工设置
if(NULL!=p)的原来是用来判断new成功还是失败的,但是这个不用了。那个是老版本的c++。现在的c++规定new失败是抛异常滴
sopro 2006-12-22
  • 打赏
  • 举报
回复
to cmail(寧采臣):
啥也不说了,给你看个effective c++上面关于operator new的伪代码:

void* operator new (std::size_t size) throw (std::bad_alloc)
{
using namespace std;
if (size == 0)
{
size = 1;
}
while(true) //注意这里得true
{
尝试分配size bytes;
if(分配成功) return (一个指针,指向分配得来得内存)
}

//分配失败
new_handler globalHandler = set_new_handler();
set_new_handler(globalHandler);

if (globalHandler) (*globalHandler)()
else throw std::bad_alloc(); //若没有设置handler,则抛出异常
}

看了这段代码,你应该认为set_new_handler针对的是operator new了把?
ppzine 2006-12-22
  • 打赏
  • 举报
回复
c++ primer 里面说过了,没有必要判断p是否为0,因为要是为0就不会调用delete
cmail 2006-12-22
  • 打赏
  • 举报
回复
OK,我明白你的意思了,set_new_handler当然是针对内建的不能改变语义的new。如果为类重载一个
operator new 当然还应定义一个set_new_handler的成员函数,当然里面仍是调用全局set_new_handler
。没有异议了。
cmail 2006-12-22
  • 打赏
  • 举报
回复
to 楼上,我明白意思,也看过Effective C++
关键我们现在不是在讨论内建new和operator new,而是他认为set_new_handler针对的是operator new
不是new.
sopro 2006-12-22
  • 打赏
  • 举报
回复
你写的代码是new

operator new是个不同于new操作符的概念,你可以把operator new看成构成new操作符内部定义的一部分。
我们可以重载operator new(用来管理内存分配),但是我们不能重载new操作符

你这么理解:
new
{
operator new //分配内存
constructor //构造对象
}

如果你设置了new_handler 函数,而且它是不抛异常,那么你写的那个程序将捕捉不到任何异常,只不过abort()了
taodm 2006-12-22
  • 打赏
  • 举报
回复
呃,楼上的,去看Effective C++,关于new operator和operator new。
cmail 2006-12-22
  • 打赏
  • 举报
回复
如果已经进入handler函数了,当然有自己的处理方法了,所以按自己的方法处理。我可以尝试着再
多次分配,或是程序运行前先申请一大块保留着,这时释放,再申请就可能成功,或是abort。我只想证明,有
handler 函数是不抛异常的。你说我指的是operator new,不是new.我不明白你的意思。那你说我给
的代码用的operator new还是new? new都是operator,操作符,难道还有不是operator的new??
sopro 2006-12-22
  • 打赏
  • 举报
回复
abort就退出了(这个程序就结束了,我们不谈这个)。如果有catch语句,一定可以捕捉到异常(或者new_handler调用的死循环)
加载更多回复(5)

64,281

社区成员

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

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