關於指標和記憶體的幾個問題
一、"delete p" 會刪去 "p" 指標,還是它指到的資料,"*p" ?
該指標指到的資料。"delete" 真正的意思是:「刪去指標指到的東西」(delete the thing pointed to by)。同樣的英文誤用也發生在 c 語言的「釋放」指標所指向的記憶體("free(p)"真正的意思是:"free_the_stuff_pointed_to_by(p)" )。
二、能 "free()" 掉由 "new" 配置到的、"delete" 掉由 "malloc()" 配置到的記憶體嗎?
不行。在同乙個程式裡,使用 malloc/free 及 new/delete 是完全合法、合理、安全的;但 free 掉由 new 配置到的,或 delete 掉由 malloc 配置到的指標則是不合法、不合理的。
三、為什麼該用 "new" 而不是 malloc() ?
建構子/解構子、型別安全性、可被覆蓋(overridability)。建構子/解構子:和 "malloc(sizeof(fred))" 不同,"new fred()" 還會去呼叫fred 的建構子。同理,"delete p" 會去呼叫 "*p" 的解構子。
型別安全性:malloc() 會傳回乙個不具型別安全的 "void*",而 "new fred()" 則會傳回正確型態的指標(乙個 "fred*")。
可被覆蓋:"new" 是個可被物件類別覆蓋的運運算元,而 "malloc" 不是以「各個類別」作為覆蓋的基準。
四、為什麼 c 不替 "new" 及 "delete" 搭配個 "realloc()" ?
避免你產生意外。當 realloc() 要拷貝配置區時,它做的是「逐位元 bitwise」的拷貝,這會弄壞大
部份的 c 物件。不過 c 的物件應該可以自我拷貝才對:用它們自己的拷貝建構子或設定運運算元。
五、該怎樣配置/釋放陣列?
用 new 和 delete :
fred* p = new fred[100];
//...
delete p;
每當你在 "new" 表示式中用了 "[...]" 的話,你就 *!*必須*!* 在 "delete" 陳述中使用 "" 。這語法是必要的,因為「指向單一元素的指標」與「指向乙個陣列的指標」在語法上並無法區分開來。
六、萬一我忘了將 "" 用在 "delete" 由 "new fred[n]" 配置到的陣列,會發生什麼事?
災難。這是程式者的--而不是編譯器的--責任,去確保 new 與 delete 的正確配對。若你弄錯了,編譯器不會產生任何編譯期或執行期的錯誤訊息。堆積(heap)被破壞是最可能的結局,或是更糟的,你的程式會當掉。
七、成員函式做 "delete this" 的動作是合法的(並且是好的)嗎?
只要你小心的話就沒事。所謂的「小心」是:
1) 你得 100% 確定 "this" 是由 "new" 配置來的(而非 "new",亦非自訂的 "new" 版本,一定要是最原始的 "new")。
2) 你得 100% 確定該成員函式是此物件最後乙個會去呼叫的。
3) 做完自殺的動作 ("delete this;") 後,你不能再去碰 "this" 的物件了,包括資料及運作行為在內。
4) 做完自殺的動作 ("delete this;") 後,你不能再去碰 "this" 指標了。換句話說,你不能檢視它、將它與其他指標或是 null 相比較、印出其值、對它轉型、對它做任何事情。
很自然的,這項警告也適用於:當 "this" 是個指向基底類別的指標,而解構子不是virtual 的場合。
八、該怎麼用 new 來配置多維陣列?
有很多方法,端視你對陣列大小的伸縮性之要求而定。極端一點的情形,如果你在編譯期就知道所有陣列的維度,你可以靜態地配置(就像 c 一樣):
class fred ;
void manipulatearray()
另乙個極端情況,如果你希望該矩陣的每個小塊都能不一樣大,你可以在自由記憶體裡配置之:
void manipulatearray(unsigned nrows, unsigned ncols)
//'nrows' 是該陣列之列數。
//所以合法的列數為 (0, nrows-1) 開區間。
//'ncols[r]' 則是 'r' 列的行數 ('r' 值域為 [0..nrows-1])。
九、怎樣確保某類別的物件都是用 "new" 建立的,而非區域或整體/靜態變數?
確定該類別的建構子都是 "private:" 的,並定義個 "friend" 或 "static" 函式,來傳回乙個指向由 "new" 建造出來的物件(把建構子設成 "protected:",如果你想要有衍生類別的話)。
class fred
static fred* create(int i)
static fred* create(const fred& fred)
private:
fred();
fred(int i);
fred(const fred& fred);
virtual ~fred();
}; main()
關於指標和記憶體的幾個問題
一 delete p 會刪去 p 指標,還是它指到的資料,p 該指標指到的資料。delete 真正的意思是 刪去指標指到的東西 delete the thing pointed to by 同樣的英文誤用也發生在 c 語言的 釋放 指標所指向的記憶體 free p 真正的意思是 free the s...
關於指標和記憶體的幾個問題
一 delete p 會刪去 p 指標,還是它指到的資料,p 該指標指到的資料。delete 真正的意思是 刪去指標指到的東西 delete the thing pointed to by 同樣的英文誤用也發生在 c 語言的 釋放 指標所指向的記憶體 free p 真正的意思是 free the s...
關於指標和記憶體的幾個問題
一 delete p 會刪去 p 指標,還是它指到的資料,p 該指標指到的資料。delete 真正的意思是 刪去指標指到的東西 delete the thing pointed to by 同樣的英文誤用也發生在 c 語言的 釋放 指標所指向的記憶體 free p 真正的意思是 free the s...