線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4110
推到 Plurk!
推到 Facebook!
[<<] [1] [2] [>>]

[C++] delete 一個字串

尚未結案
jackyung
一般會員


發表:22
回覆:46
積分:13
註冊:2004-01-24

發送簡訊給我
#32 引用回覆 回覆 發表時間:2005-03-02 18:52:46 IP:218.171.xxx.xxx 未訂閱
引言: 會有delete和delete[]的不同要從compiler層去著眼,以本例來說你在執行期要釋放的是一個char*的資料型,但是compiler是無法在編釋時就知道char*到底是單純一個指標,還是一個array(而且array還有大小的不同)。 如果是一個array,釋放的區域大小是物件本身大小乘以個數,這些會記錄在heap相關的table裡。如果是用delete,釋放時根本不需要去找heap的資料表,直接釋放和資料大小相同的區域。如果語法上不區分delete和delete[],要如何知道要不要去讀heap的資訊? 這些資訊書本上是可以找到的,在Bjarne Stroustrup的The C Programming Language中有很明白的說明,請參考一下吧。
delete [] 除了去一個個呼叫物件陣列中的解構函數外,就歸還空間的方式 和 delete 會有不同嗎?如果 delete 是歸還一個單位的空間,以下的程式 就不應兩次都取得同一個位址。 如果兩者就歸還空間的方式都一樣,對於不須呼叫解構函數的普通形別為 什麼還要用 delete [] 來刪除普通形別的陣列 我不太會表達,不知這樣是不是把問題說清楚了
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char string[25];      char *A1 = new char[10];  // 得到 10 個 byte
  ultoa((unsigned)&(A1[0]),string,16);
  Edit1->Text = AnsiString(string);
  delete A1;                // 若只是刪 1 byte      char *A2 = new char[5];   // 得到 5 個 byte
  ultoa((unsigned)&A2[0],string,16);
  Edit2->Text = AnsiString(string);  // 就不應得到相同的位址
  delete A2;
}    
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#33 引用回覆 回覆 發表時間:2005-03-02 19:30:08 IP:211.76.xxx.xxx 未訂閱
引言: delete [] 除了去一個個呼叫物件陣列中的解構函數外,就歸還空間的方式 和 delete 會有不同嗎?
在bcb中,是同樣的方式。(非bcb我就不確定了)
引言: 如果兩者就歸還空間的方式都一樣,對於不須呼叫解構函數的普通形別為 什麼還要用 delete [] 來刪除普通形別的陣列
我的想法有二個,一個是語法的統一性。總不能說釋放class的array用delete[],而釋放基本資料型的array就用delete吧? 第二個是,C語言設計的目的不是針對單一平台或系統。因此編譯器配置heap的做法是各家做各的,只要能符合標準就好。世界上系統和編譯器上百種,無法保證有平台可以不需要區分delete和delete[]。如果這些都沒有考慮到,C是無法廣泛運用在各平台的。 發表人 - pwipwi 於 2005/03/02 19:44:53
jackyung
一般會員


發表:22
回覆:46
積分:13
註冊:2004-01-24

發送簡訊給我
#34 引用回覆 回覆 發表時間:2005-03-02 21:44:43 IP:218.171.xxx.xxx 未訂閱
這就回到起初我所提到面對字串宣告的問題,同樣面對 char *s 這變數的使用,s 可被視為單一物件用 delete 來刪,也可被視為陣列用 delete [] 來刪,編譯器無法幫忙分辨,如果當初規定 delete 用來刪 char *s,delete [] 用來刪 char s[](這個是我假定的,不是 C 那個),這就很清楚了,或者 都統一用 delete 或 delete [] 交由系統去處理就完美。 既然現實情況 delete 和 delete [] 皆可刪 char *s,只好探究兩者歸還空間的方式有沒有可能不同,用 new 去得到一塊陣列空間,若真有一個平台用 delete 只是會刪陣列空間的第一個單位,那麼其他陣列空間如何保留下來,是不是得去調 heep,可是這一調整出來的保留空間並沒有任何指標去指向,因此等於是變成垃圾,因此我不相信有任何平台會這樣做。當初定義出 delete 和 delete [] 兩個刪除方式很讓人頭大。 如暗黑破壞神所說的,程式是自己設計的,怎麼 new 就怎麼刪,自己 new 的自己刪就不會間題了。可是也得面對現實,比如對 list 這容器,它是用複製物件的方法來保存物件,雖很安全,但一會帶來效率問題,二會因使用上的須要須保存物件本尊而不是分身,三是想要保存的是延伸類別,就不能用複製物件的方式來保存。總之若自己須打造 list 用來直接保存由外界傳來的物件,而會造成 delete 不是自己 new 的物件,馬上須面對 delete 和 delete [] 的問題,無法確定外界傳來的是不是陣列,全用 delete [] 是不是可以解決這種情況,要是能有高階一點的刪除方式就好了,大家有什麼看法
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#35 引用回覆 回覆 發表時間:2005-03-03 00:06:39 IP:211.76.xxx.xxx 未訂閱
這個問題..和很多議題有關,我提供一些東西讓你參考看看~    現在的這一版的C++標準在幾年前出來後,大概底定了template的主要架構和功能,已經可以說是很完美了。但是還是有個C時代的老問題一直是沒有好的解決方案:"Pointer"。    指標還是老樣子,不會用的人常常寫到程式crash,會用的人不小心也用弄到AV。去年在C++ moderated討論區還有一連串"激烈"的討論,爭論garbage collection是不是要納入下一版的C標準....雖然如此,有一個解決的方案一定會在下一版C++的標準中加入:share_ptr。    share_ptr是一個專門處理和配置記憶體的class, 最重要的是他自動負責記憶體的釋放, 很安全~copy safe, exception safe,而且運用了相當好的reference counting技術,很省空間,唯一的缺點是大小至少會有8bytes(不包含被配置的物件)。在運用template的技術下,透過share_ptr和直接使用pointer在效率上是幾乎一樣的。share_ptr還可以很安全的和STL中任何的容器結合,以jackyung網友的效率問題,list加share_ptr就可以解決了。(附註:auto_ptr是禁止和STL container合用的)(註2:如果我沒記錯,VCL的AnsiString好像也是運用了reference counting,因此在copy時空間需求和運算時間都很省)    雖然說這個討論串是討論delete...不過我已經很少直接用到delete這個關鍵字。程式中的存在於heap的class幾乎全由share_ptr和auto_ptr自動管理,memory leakage是不太可能發生的。另外有了share_ptr, auto_ptr,在處理exception時就可以把finally丟了..。好處不止這些....現在很多的 > 發表人 -
jackyung
一般會員


發表:22
回覆:46
積分:13
註冊:2004-01-24

發送簡訊給我
#36 引用回覆 回覆 發表時間:2005-03-03 18:07:52 IP:218.171.xxx.xxx 未訂閱
謝謝版主指導,我去了解一下,有問題再來請教,謝謝....
[<<] [1] [2] [>>]
系統時間:2024-05-07 15:19:32
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!