本文不太完整,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;
}
}