本文不太完整,C++中还有引用,这种情况构造应该认为分配了空间,同时引用也支持多态,支持大数据类型。
另外,对象分配区域似乎意义不大,栈其实也是一种堆,并没有特别之处。
呵呵 能把B题的代码发给我们参考一下么?
315009476@qq.com
谢谢了啊。。
re: 一个要引起注意的delete动作 anthony 2007-07-26 11:53
哈哈,抱歉,终于知道我哪里出问题了,你看下是不是这里:
# re: 一个要引起注意的delete动作 2007-04-17 18:09 lele
呵呵 我都被你误导了 temp != list_tail->back 和 temp != NULL
这两局并没有区别 list_tail->back 就是NULL
在list_tail没被删除前,这两句的确是一样的,可list_tail->back被删后,这就不一样了,因为temp没有引用->back,而list_tail引用了back,而list_tail被删除了,所以不能引用list_tail->back,而就像你前面告诉我的
# re: 一个要引起注意的delete动作 2007-04-14 23:11 lele
temp != list_tail->back && temp != NULL这里依然有个问题就是
先判断temp != list_tail->back会出错,还是把两个语句调换一下位置
这样就能保证安全性了 呵呵
还是你提醒了我
# re: 一个要引起注意的delete动作 2007-06-07 14:25 lele
问题不是出在temp是出在list_tail->back
list_tail对back的操作
back已经被释放了,不可再访问
你是不是敲错了,是list_tail被释放了??呵呵
谢谢你的指点啊,经过这样讨论,我觉得应该对指针和链表的认识又进一步了,谢谢你啊,呵呵
re: 一个要引起注意的delete动作 anthony 2007-07-26 11:35
list_tail->back不就是null吗?它没有指向哪个对象,只是指向null那个地址0x00000000,而已,null就是0x00000000,没有指向哪个对象,呵呵,
好长时间没过来了,不知道你是否也还记得你所写的,和我们讨论的,我刚是从头到尾又看了编。
acm亚洲银奖?那很厉害的,同时呢我也参加过acm,也见过好多acm的同学的代码,还有网上的一些比较厉害的人的代码,因为他们追求的是速度,不管是算法效率,还是敲程序的速度,所以我看过的acm代码的风格没有你写得好,我还记得我那时候见他们敲字得速度,惊讶得说不出话来了,呵呵
re: 一个要引起注意的delete动作 anthony 2007-05-12 10:14
呵呵,同意编程不能靠运气。
可能我水平太低吧,不能理解指针的真正含义?也不能理解你的意思。
我实在不明白list_tail->back=null,然后temp=list_tail->back,然后temp不是指向了null吗?对于一个指针我觉得可以对它进行任何赋值,然后temp!=null只是拿存放指针本身的那块内存里面的数值去和0X0000000内存地址比较,即使指向的内容被析构了,但指针它同样占着它的内存空间,拿temp和null比只是存放temp指针那块内存里面的数值和null比,不是存放temp指针的那块内存里面的数值指向的内存,怎么会出错呢?
不过你的代码看起来真的很舒服,不知道你是怎么做到的,就是我写的时候缩排格式,我也一直在注意,按照《高质量程序设计指南 C++/C语言》 上面的写法来写的,但还是感觉有点乱,是不是注释写得太多会显得乱呢?这方面得向你请教,呵呵
re: 一个要引起注意的delete动作 anthony 2007-04-17 21:45
对啊,所以你不是说要给它换个顺序变成
while(temp != NULL && temp != list_tail->back )吗?这样不就安全了吗?
如果你是这个意思,下面的就别看了,这样不就安全了吗?还能有什么问题吗?
可能我理解NULL有问题,我觉得NULL就相当于一个const变量,它永远指向内存中的一个不存在的地方,“ list_tail->back 就是NULL ”没错,然后当temp指向list_tail时,然后根据while(temp!=NULL)进入循环体,接着deltemp就指向了list_tail,然后temp = temp_back,就是此时,
temp=NULL,然后删除了list_tail,然后判断时,temp不是等于NULL了吗?然后循环条件成立不了,
我的理解是NULL是指向一个相当于CONST的地址空间,不管list_tail有没有,我们都可以指向NULL,NULL和list_tail 没关吧?
还有说的“List_tail指向的内容被析构之后 系统就会给List_tail分配一个我们无法得知的指向”,我觉得它还是指向原来那个地方吧?
我观察了下面的代码
int *p = NULL;//此时p指向0x00000000
p = new int [200];//此时p指向0x00441ac0
delete p;
cin>>a;//此时p还指向0x00441ac0
然后还有
temp != list_tail->back 和 temp != NULL
对于前面的节点时它们是一样的,但在最后那个点时,即deltemp = list_tail时,然后temp = temp->back(就是NULL)了,然后系统把list_tail删了,然后list_tail还指向那个系统单元(就是只是系统把房子里的人赶了出去,但门牌号还是那个),然后再进入循环条件,然后此时list_tail->back 引用就会出错了,因为list_tail里面已经没“人”了,在加一个back相当里面的一个人,所以会出错,
不知道你能否明白我的意思,或者可能我没明白你的意思,还有一个就是NULL的问题,就是temp的指向的内容被回收,但它还是可以指向地址,现在就是指向NULL,只要temp!=NULL,只是判断temp的数值而已,呵呵,写着写着就变很罗嗦了,呵呵
re: 判断一个数是否为2的N次方 anthony 2007-04-16 18:35
其实就是根据二进制的原理,将数转换为二进制后,如果是2的N次方,则其最高位为“1”,后面的都为“0”,而n-1即为除高位外全为“0”,利用了在计算机内的数全是2进制,所以利用与关系,呵呵,不错
re: 一个要引起注意的delete动作 anthony 2007-04-16 09:41
以前倒还真没注意过和顺序有关,又学到了,看来讨论真的能有意外的收获,谢谢你的指正
呵呵,听你这么一说,然后觉得是不是while(temp != NULL)就可以了?
还是得用随机种子来设置随机数,否则洗出来的牌好像还是原先的牌
re: 一个要引起注意的delete动作 anthony 2007-04-14 14:29
你的clear函数只是清空了链表的内存空间listitem,并没有删除list这个对象,对象的删除得由析构函数来执行
比如你执行了一个LIST Object,只是一个链表对象,往里面加item,然后clear方法Object.Clear()只是删除了里面的item的空间,而成员对象是否应该还存在?就是List_tail还是一个指针,它还有它的值,它指向它原先的内存地址,我的理解是比如List_tail现在是一个门牌号101,而item是里面的人,里面如果搬家了,执行的是Clear,但门牌号还在,而只有把房子给拆了,才是把对象给释放了,或者你可以试一下把List_tail设为公有,然后Clear()后,然后List_tail = 0x16;这说明List_tail还是存在,它还指向那片内存单元,或者你跟踪一下,在执行Clear之前,看下list_tail的地址,Clear之后,在看下那地址,是不是一样的,temp也只是个指针,无论后面的list_tail-back存不存在,它还是个内存中的一个编号(门牌号),如果存在,程序正确,不存在,就是野指针,个人认为只要它值为NULL它就不应该是野指针,我说的应该是list_tail是野指针,是因为当最后deltemp也指向list_tail时,temp = list_tail->back = NULL;此时由于delete deltemp;
list_tail空间就不存在了,但它还指向那个地址,但是后面就没有back了,所以会出错
如果改成
while(temp != list_tail->back && temp != NULL), 当然这个没你的算法好,这个得多做多个判断,时间负责度比你原先的高,就是感觉要说引用了不存在的对象应该是list_tail引用了不存在的对象,你觉得呢?(个人愚见)
re: 一个要引起注意的delete动作 anthony 2007-04-14 10:53
你的意思是temp=list_tail->back ;时,deltemp等于list_tail,然后删除了deltemp,相当于删了list_tail,这样我觉得应该是list_tail变成了野指针吧(其实都一样),我的想法是这样的,如果list_tail->back = NULL ,temp就变成了NULL,而应该是list_tail变成了野指针,我知道这是有点钻死胡同的感觉(因为结果是一样的),我只是把为什么我不理解你的程序的那些注释说出来而已,讨论清楚而已,你觉得是不是应该是list_tail是野指针,而不是temp?
不过说真的我光注意前面的temp了,而没注意后面的tail_back(就while的条件里面),看来以后还得注意前后
re: 一个要引起注意的delete动作 anthony 2007-04-13 12:40
不知道你之前的代码是不是只是while那里不一样,
个人感觉不是temp的问题,如果照你以前的写法,应该是是最后的delete list_tail;的问题
void clear()
{
if( !isEmpty() )
{
list_item< type >* temp = list_head;
list_item< type >* delTemp;
while( temp != list_tail->back)//你以前的写法
{
delTemp = temp;
temp = temp->back;
delete delTemp;//释放空间
}
// delete list_tail; //这句不要了,因为delTemp 总是指向temp的前一个,当temp = list_tail->back时是在最后,此时delTemp = list_tail已删除完整个链表,觉得如果你之前的语句只是while那里不一样,应该是这里出错了,不知道有没有理解你原来的意思。觉得有点疑问
list_head = NULL;
size = 0;
}
else
{
return;
}
}