您的位置:首页 > 其它

请教:a 和 *(&a) 有什么区别,"delete a" 和 "delete []a"又有什么区别?

2008-10-27 17:33 567 查看
请教:a 和 *(&a) 有什么区别,"delete a" 和 "delete []a"又有什么区别?



[已结贴,结贴人:yaoike]



加为好友
发送私信
在线聊天



yaoike
想念着Run的Ike
等级:


可用分等级:乞丐
总技术分:0
总技术分排名:313963
揭贴率:100.00%

发表于:2007-08-23 17:56:20 楼主
见题目,我上google都查不到相关的解释,麻烦您解答一下,说一下你的看法和观点,非常感谢!!!
问题点数:70 回复次数:26 显示所有回复显示星级回复显示楼主回复 修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



Microsoft777
TMD倒分被抓了
等级:


可用分等级:中农
总技术分:225
总技术分排名:55662

发表于:2007-08-23 18:00:491楼 得分:5
a 和 *(&a) 是等效的
"delete a " 和 "delete []a " 前者删除一个元素 后者删除一组元素
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



hoya5121
饿了就喝水
等级:


可用分等级:乞丐
总技术分:3170
总技术分排名:6567

发表于:2007-08-23 18:00:542楼 得分:5
"delete a " 和 "delete []a "

a = new A;
delete a;
...........

a = new A[10];
delete []a;
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



gfxiang
afu
等级:


可用分等级:中农
总技术分:3658
总技术分排名:5663

发表于:2007-08-23 18:14:003楼 得分:5
a和*(&a)等价

delete a和delete [] a是有区别的
delete a释放a所指的内存,如果a是类对象,还会调用a的析构函数
delete [] a释放a所指数组的内存,如果a是类对象,分别调用每个数组元素a[i]的析构函数
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



fmjk525283

等级:


可用分等级:长工
总技术分:310
总技术分排名:45213

发表于:2007-08-23 18:25:574楼 得分:10
楼上的delete解释的很完美了

C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。

关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。

对于 (1),上面提供的程序已经证明了 delete[] 和 delete 是等同的。但是对于 (2),情况就发生了变化。请看下面的程序。

#include <iostream> ;using namespace std;class T {public: T() { cout < < "constructor " < < endl; } ~T() { cout < < "destructor " < < endl; }};int main(){ const int NUM = 3; T* p1 = new T[NUM]; cout < < hex < < p1 < < endl; // delete[] p1; delete p1; T* p2 = new T[NUM]; cout < < p2 < < endl; delete[] p2;}

大家可以自己运行这个程序,看一看 delete p1 和 delete[] p1 的不同结果,我就不在这里贴运行结果了。

从运行结果中我们可以看出,delete p1 在回收空间的过程中,只有 p1[0] 这个对象调用了析构函数,其它对象如 p1[1]、p1[2] 等都没有调用自身的析构函数,这就是问题的症结所在。如果用 delete[],则在回收空间之前所有对象都会首先调用自己的析构函数。

基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。

所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



wpp_zyt

等级:


可用分等级:乞丐
总技术分:11
总技术分排名:209673

发表于:2007-08-23 18:46:575楼 得分:5
a 和 *(&a) 是等效的
"delete a " 和 "delete []a " 前者删除一个元素 后者删除一组元素

修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



iatsbg

等级:


可用分等级:短工
总技术分:1399
总技术分排名:14606

发表于:2007-08-23 19:21:266楼 得分:5
a和*(&a)不一定等效啊~~operator&是可以重载的,尽管这不是好的做法。
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



fish6344
顽童
等级:


可用分等级:中农
总技术分:1123
总技术分排名:18131

发表于:2007-08-23 23:46:237楼 得分:10
a 和 *(&a) 没有区别!

有如下代码可以演示证明:

int main()
{
long a = 7;//这是你的那个‘a '演示值;

long b = a;//以变量a提领,以演示 "a ":
cout < < "演示a: " < < b < < endl;//显示出 "演示a: 7 "!

long c = *(&a);//以地址提领与指针操作符的组合演示 "*(&a) ":
cout < < "演示*(&a): " < < c < < endl;//显示出 "演示*(&a): 7 "!

_PAUSE;//一个便于观察演示的宏。
return 0;
}//演示该程序足以令你看到第1个问题的解。

如果有如下类:

class Pig
{
public:
Pig(){};
};

那么在堆上创建1个Pig对象,例如:

Pig* _pig = new _pig;//实际调用的是void* operator new(size_t) throw(bad_alloc);

上述语句的实现细节是:

第一步: Pig* _pig = _new(sizeof(pig));//内存资源获取,长度是sizeof(pig);
第二步: if(_pig) _pig = Pig::Pig(_pig);//C++伪码:调用Pig的构造函数;

重要的是第一步,内存资源申领的长度是1个对象的sizeof运算值!
第二步中的C++伪码我们是看不到的,但这的确是真的,其中构造函数参数表中那个_pig即是对象的this指针。(见《Inside The C++ Object Model》page255)这就是new运算符的实现细节!

如果我们在堆上创建一个Pig数组,例如:

Pig* _pigs = new Pig[3];
//实际调用的是: void* operator new[](size_t) throw(bad_alloc);

上述语句的实现细节是:

代码由编译器处理成:

Pig* _pigs = vec_new(0,sizeof(Pig),3,&Pig::Pig,&Pig::~Pig);

上述vec_new()函数或其类似的东东存在于C++的库文件(C++ Runtime Library)中,它体现具体的编译器对数组的构建策略。

注意;重要的是第2及第3个参数指定了内存空间的申领长度是 sizeof(Pig)* 3,以此容纳3个Pig对象,在vec_new()中还会调用第4个参数指定的可能存在的构造函数!

到此,相信你已经看到了new与new[]的不同。

最终,我们会删除在堆上创建的Pig对象,归还单个的Pig对象所占有的堆空间,例如:

delete _pig;//这是C++程序员的责任,不愿意的话就改行去学习Java!

对于delete,C++出于效率的考虑,它断定_pig指针一定是指向单个的Pig对象,因此简单的释放_pig所指向之地址,长度为sizeof(Pig)的堆内存空间。

那么我们最终还会删除在堆上创建的由_pigs指向的Pig数组,那么我们怎样告诉编译器,_pigs指向的空间是3个Pig对象所组成的Pig数组呢?这就是delete[]中的 '[] '!

Stanley B.Lipman博士告诉我们: "寻找数组的维度给delete运算符的效率带来极大的影响,所以才导至这样的妥协:只有在中括号出现时,编译器才寻找数组的维度,否则它便假设只有单独一个对象要被删除。 "(见《Inside The C++ Object Model》page259)

这就是delete与delete[]的不同之处!

修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



iatsbg

等级:


可用分等级:短工
总技术分:1399
总技术分排名:14606

发表于:2007-08-24 01:03:478楼 得分:8
a和*(&a)几乎没有区别,a和*(&a)几乎是等效的。

如果a是内建类型,那么a和*(&a)的确是等效的。
我说a和*(&a)可能不等效(尽管这是很极端的情况),是因为如果a是类,而该类重载了address-of操作符,那么&a就不一定返回a的真实地址,*(&a)也就和a不一定等效了。
例如:
template <class T> //载自《C++设计新思维》P170
class SmartPtr
{
public:
T** operator&()
{
return &pointee_;
}
...
};
如果a是SmartPtr <int> 类型,那么*(&a)则是int*类型。显然,a和*(&a)有区别,a和*(&a)不再等效了。
PS:重载address-of操作符是不是好的设计!
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



jixingzhong
瞌睡虫·星辰
等级:


可用分等级:掌柜
总技术分:119657
总技术分排名:37

2

17

2



发表于:2007-08-24 07:47:469楼 得分:5
a 和 *(&a) 有什么区别
============
等效。
* & 是一对反操作,类似 */, /一下再*一下,结果自然一样[理论上]。

"delete a " 和 "delete []a "又有什么区别
===================
delete a 释放一个元素空间
delete[] a 释放一组元素空间,这个组有多少个元素,由new分配时候确定
【该组长度信息的保存,根据 Allocator确定】
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



farmerice

等级:


可用分等级:长工
总技术分:1
总技术分排名:296708

发表于:2007-08-24 08:40:2310楼 得分:0
fish6344() ( ) 信誉:100
写的很认真哦...谢谢呢,呵呵~就是言辞犀利了些~大家讨论嘛...嘿嘿
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



scrutin
所谓伊人,在水一方
等级:


可用分等级:贫农
总技术分:213
总技术分排名:57438

发表于:2007-08-24 08:46:4211楼 得分:0
大家讨论得挺好 我就进来接分了 ^_^
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



jhs1982419
我很笨,但我能飞的更高
等级:


可用分等级:中农
总技术分:3766
总技术分排名:5486

发表于:2007-08-24 10:06:0912楼 得分:3
a和*(&a)没有区别

delete a释放a所指的内存

delete [] a释放a所指数组的内存
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



lfcai
享受一切
等级:


可用分等级:贫农
总技术分:318
总技术分排名:44424

发表于:2007-08-24 12:09:3913楼 得分:3
a 和 *(&a) 没有区别

delete a 删除一个元素 delete []a 删除一组元素(数组)
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



higter
川湘菜
等级:


可用分等级:富农
总技术分:300
总技术分排名:46741

发表于:2007-08-24 12:14:2114楼 得分:0
哇,这么多人回答?
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



lkldiy
最近眼睛涩
等级:


可用分等级:富农
总技术分:156
总技术分排名:69313

发表于:2007-08-24 12:44:2515楼 得分:0
没什么说的了
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



yc_8301
草根程序员
等级:


可用分等级:富农
总技术分:406
总技术分排名:39975

发表于:2007-08-24 12:54:0616楼 得分:0
都说完了,支持一下。。
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



charlen
.......
等级:


可用分等级:贫农
总技术分:57
总技术分排名:118558

发表于:2007-08-24 12:58:2217楼 得分:0
fish6344 正解~
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



tncqsy
中秋节了,吃月饼呀!
等级:


可用分等级:富农
总技术分:191
总技术分排名:61526

发表于:2007-08-24 14:02:2218楼 得分:0
同意:iatsbg() ( ) 的
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



Nowish
看我能忍耐多久
等级:


可用分等级:富农
总技术分:867
总技术分排名:21579

发表于:2007-08-24 14:26:5219楼 得分:0
o
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



zkcq2004

等级:


可用分等级:中农
总技术分:1426
总技术分排名:14589

发表于:2007-08-24 15:16:5220楼 得分:3
a和*(&a)几乎没有区别,a和*(&a)几乎是等效的。

delete a 删除一个元素 delete []a 删除一组元素(数组)
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



bsnail
小马
等级:


可用分等级:富农
总技术分:109
总技术分排名:85042

发表于:2007-08-24 15:45:3821楼 得分:0
都说完了
留个脚印吧
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



langkefeixia
leke
等级:


可用分等级:短工
总技术分:102
总技术分排名:88036

发表于:2007-08-24 15:59:0522楼 得分:0
学习了
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



expter
Give to dream of a new height,My2008!
等级:


可用分等级:富农
总技术分:1772
总技术分排名:11793

发表于:2007-08-24 16:14:5523楼 得分:0
up
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



xxyyboy
【壮志凌云】
等级:


可用分等级:富农
总技术分:1944
总技术分排名:10811

发表于:2007-08-24 16:42:5624楼 得分:3
a 和 *(&a) 没有区别
----------------------
说有区别的人来了。。。。。
a可以认为是1个队形,但是 &a 你可以认为是取对象的地址,你也可以认为是引用。。。。
加上引用就不一样了吧。哈哈哈
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



fish6344
顽童
等级:


可用分等级:中农
总技术分:1123
总技术分排名:18131

发表于:2007-08-26 19:58:0325楼 得分:0
farmerice()朋友批评得是,但我来CSDN论坛是想和大家共同研讨,共同受益!再次向朋友们致意,绝没有贬谁的意思,语言有时率直一些,请朋友们一定海涵,谢谢!
修改 删除 举报 引用 回复



加为好友
发送私信
在线聊天



fish6344
顽童
等级:


可用分等级:中农
总技术分:1123
总技术分排名:18131

发表于:2007-08-26 21:16:1826楼 得分:0
iatsbg()朋友提出的 "a如果是自定义类型,且又重载了 '& '运算符, "则 "a和*(&a)可能不等效 "的情况,我想和大家讨论如下:

从技术上说,自定义类型类重载的运算符,可以随心所欲,例如有如下类:

class A
{
mutable long a;
public:
A(){ a = 7;}
long operator++(void) const//一个改变运算符语义的重载!
{
return --a;
}
void show(void)
{
cout < < "a: " < < a < < endl;
}
};

你可以看到:

int main()
{
A _a;
_a.show();//这将显示A成员a的初始值为7!

++_a;
_a.show();//这将显示A成员a的--结果为6!

_PAUSE;
return 0;

}

上述重载的 '++ '运算符,已经改变了内建 '++ '运算符的语义!

iatsbg()朋友提出的问题与此类似,主要是担心 '& '经重载后,改变了内建 '& '运算符的语义。如此一来,当然 "a和*(&a)可能不等效 "。

我想说的是,上述重载的行为,是一个C++程序员不应有的重载!虽然技术可行,但却违背了语言对重载运算符支持的初衷!C++因为对重载运算符提供支持,使我们的自定义类型也象内建类型一样支持内建运算符的语言高阶特性,隐藏运算符实现的底层实现。一句话,无论 '& '运算符重载的底层实现如何,程序员有责任维护 '& '运算符的高阶语意-那就是地址提取!进一步推论:就是要保证 "a和*(&a)等效 "!

所以对于可能的正确的重载 "& "运算符,a和*(&a)同样等效!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐