CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

delete和delete[]的区别?

楼主BooBio(痲婆豆腐)2006-03-07 10:07:54 在 C/C++ / C++ 语言 提问

在标准C++中,对于基本数据类型的数组,使用delete[]和delete的效果是一样的么?  
  比如:  
  int*   i   =   new   int[100];  
  int*   c   =   new   char[100];  
  delete   i;   //等同于delete[]   i;?  
  delete   c;   //等同于delete[]   c;?  
  那位大大能够解释一下啊? 问题点数:20、回复次数:5Top

1 楼asdfg014(绝望生鱼片)回复于 2006-03-07 10:14:05 得分 0

不了解~帮你顶一下Top

2 楼Rick_ang(东方未名)回复于 2006-03-07 10:16:27 得分 0

不一样..Top

3 楼windking21(想玩玩WOW 真的那么难吗)回复于 2006-03-07 10:19:13 得分 0

 
   
  --------------------------------------------------------------------------------  
     
   
   
  条款3:尽量用new和delete而不用malloc和free  
   
  malloc和free(及其变体)会产生问题的原因在于它们太简单:他们不知道构造函数和析构函数。  
   
  假设用两种方法给一个包含10个string对象的数组分配空间,一个用malloc,另一个用new:  
   
        
   
  string   *stringarray1   =  
  static_cast<string*>(malloc(10   *   sizeof(string)));  
   
  string   *stringarray2   =   new   string[10];  
   
  其结果是,stringarray1确实指向的是可以容纳10个string对象的足够空间,但内存里并没有创建这些对象。而且,如果你不从这种晦涩的语法怪圈(详见条款m4和m8的描述)里跳出来的话,你没有办法来初始化数组里的对象。换句话说,stringarray1其实一点用也没有。相反,stringarray2指向的是一个包含10个完全构造好的string对象的数组,每个对象可以在任何读取string的操作里安全使用。  
   
  假设你想了个怪招对stringarray1数组里的对象进行了初始化,那么在你后面的程序里你一定会这么做:  
   
   
  free(stringarray1);  
  delete   []   stringarray2;//   参见条款5:这里为什么要加上个"[]"  
   
  调用free将会释放stringarray1指向的内存,但内存里的string对象不会调用析构函数。如果string对象象一般情况那样,自己已经分配了内存,那这些内存将会全部丢失。相反,当对stringarray2调用delete时,数组里的每个对象都会在内存释放前调用析构函数。  
   
  既然new和delete可以这么有效地与构造函数和析构函数交互,选用它们是显然的。  
   
  把new和delete与malloc和free混在一起用也是个坏想法。对一个用new获取来的指针调用free,或者对一个用malloc获取来的指针调用delete,其后果是不可预测的。大家都知道“不可预测”的意思:它可能在开发阶段工作良好,在测试阶段工作良好,但也可能会最后在你最重要的客户的脸上爆炸。  
   
  new/delete和malloc/free的不兼容性常常会导致一些严重的复杂性问题。举个例子,<string.h>里通常有个strdup函数,它得到一个char*字符串然后返回其拷贝:  
   
   
  char   *   strdup(const   char   *ps); //   返回ps所指的拷贝  
  在有些地方,c和c++用的是同一个strdup版本,所以函数内部是用malloc分配内存。这样的话,一些不知情的c++程序员会在调用strdup后忽视了必须对strdup返回的指针进行free操作。为了防止这一情况,有些地方会专门为c++重写strdup,并在函数内部调用了new,这就要求其调用者记得最后用delete。你可以想象,这会导致多么严重的移植性问题,因为代码中strdup以不同的形式在不同的地方之间颠来倒去。  
   
  c++程序员和c程序员一样对代码重用十分感兴趣。大家都知道,有大量基于malloc和free写成的代码构成的c库都非常值得重用。在利用这些库时,最好是你不用负责去free掉由库自己malloc的内存,并且/或者,你不用去malloc库自己会free掉的内存,这样就太好了。其实,在c++程序里使用malloc和free没有错,只要保证用malloc得到的指针用free,或者用new得到的指针最后用delete来操作就可以了。千万别马虎地把new和free或malloc和delete混起来用,那只会自找麻烦。  
   
  既然malloc和free对构造函数和析构函数一无所知,把malloc/free和new/delete混起来用又象嘈杂拥挤的晚会那样难以控制,那么,你最好就什么时候都一心一意地使用new和delete吧。  
     
  Top

4 楼windking21(想玩玩WOW 真的那么难吗)回复于 2006-03-07 10:19:43 得分 20

条款5:对应的new和delete要采用相同的形式  
   
  下面的语句有什么错?  
   
   
  string   *stringarray   =   new   string[100];  
   
  ...  
   
  delete   stringarray;  
   
  一切好象都井然有序——一个new对应着一个delete——然而却隐藏着很大的错误:程序的运行情况将是不可预测的。至少,stringarray指向的100个string对象中的99个不会被正确地摧毁,因为他们的析构函数永远不会被调用。  
   
  用new的时候会发生两件事。首先,内存被分配(通过operator   new   函数,详见条款7-10和条款m8),然后,为被分配的内存调用一个或多个构造函数。用delete的时候,也有两件事发生:首先,为将被释放的内存调用一个或多个析构函数,然后,释放内存(通过operator   delete   函数,详见条款8和m8)。对于   delete来说会有这样一个重要的问题:内存中有多少个对象要被删除?答案决定了将有多少个析构函数会被调用。  
   
  这个问题简单来说就是:要被删除的指针指向的是单个对象呢,还是对象数组?这只有你来告诉delete。如果你在用delete时没用括号,delete就会认为指向的是单个对象,否则,它就会认为指向的是一个数组:  
   
   
  string   *stringptr1   =   new   string;  
  string   *stringptr2   =   new   string[100];  
   
  ...  
   
  delete   stringptr1;//   删除一个对象  
  delete   []   stringptr2;//   删除对象数组  
   
  如果你在stringptr1前加了"[]"会怎样呢?答案是:那将是不可预测的;如果你没在stringptr2前没加上"[]"又会怎样呢?答案也是:不可预测。而且对于象int这样的固定类型来说,结果也是不可预测的,即使这样的类型没有析构函数。所以,解决这类问题的规则很简单:如果你调用new时用了[],调用delete时也要用[]。如果调用new时没有用[],那调用delete时也不要用[]。  
   
  在写一个包含指针数据成员,并且提供多个构造函数的类时,牢记这一规则尤其重要。因为这样的话,你就必须在所有初始化指针成员的构造函数里采用相同的new的形式。否则,析构函数里将采用什么形式的delete呢?关于这一话题的进一步阐述,参见条款11。  
   
  这个规则对喜欢用typedef的人来说也很重要,因为写typedef的程序员必须告诉别人,用new创建了一个typedef定义的类型的对象后,该用什么形式的delete来删除。举例如下:  
   
   
  typedef   string   addresslines[4]; //一个人的地址,共4行,每行一个string  
  //因为addresslines是个数组,使用new:  
  string   *pal   =   new   addresslines; //   注意"new   addresslines"返回string*,   和  
  //   "new   string[4]"返回的一样  
  delete时必须以数组形式与之对应:  
  delete   pal;//   错误!  
  delete   []   pal;//   正确  
   
  为了避免混乱,最好杜绝对数组类型用typedefs。这其实很容易,因为标准c++库(见条款49)包含有stirng和vector模板,使用他们将会使对数组的需求减少到几乎零。举例来说,addresslines可以定义为一个字符串(string)的向量(vector),即addresslines可定义为vector<string>类型。  
   
  Top

5 楼BooBio(痲婆豆腐)回复于 2006-03-07 10:24:02 得分 0

ok,了解了,thank   uTop

相关问题

  • delete 和 delete [] 有何区别?
  • delete 和delete[]的区别
  • delete和truncate table区别!
  • delete和truncate的区别?
  • delete 和 delete[] 有什么区别呀?
  • delete[] p和delete p有什么区别?
  • free和delete有什么区别?
  • delete在IE和Netscape上的区别
  • delete ptr 和 ptr=0有什么区别?
  • 关于delete p和delete []p的区别所在

关键词

  • c++
  • 函数
  • 内存
  • 指针
  • 程序员
  • 代码
  • 数组
  • 调用
  • stringarray
  • delete

得分解答快速导航

  • 帖主:BooBio
  • windking21

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo