delete與delete[]需要注意的地方
轉自:http://wenku.baidu.com/view/0e3d8c1cfc4ffe473368ab5c.html
1:首先來說一個大家容易忽略的問題:
定義:int*p=new int;
這個大家一看就知道,在記憶體中分配了一個int型別的空間,沒錯。但是我想說的是,作業系統在堆在分配了一個int型別空間給p指向的空間,但是p本身的值是在棧上,我覺的明白這個很重要。比如,你需要處理一個海量資料,這個資料需要用二維陣列來表示,你如果這樣定義int *ptr[MaxNum],然後再迴圈為每個ptr[0~MaxNum-1]分配空間,這個時候容易隱含一個錯誤,我們知道記憶體中棧的大小大約就2M左右,而堆很大,幾乎沒有限制,當你的MaxNum很大的時候,就會導致記憶體溢位,因為ptr這個值的本身是在棧上的,而棧的大小就2M左右,而你又有這麼多個地址要存放,所以會出錯。解決辦法有二個:一:用一維資料代替二維陣列;二:定義一個二維指標;然後再動態分配。
2:delete與delete[]執行遇到的問題:
① int *p=new int[100];
int num[100];
p=num;
delete []p;
大家能看出這段程式碼有什麼問題嗎?如果你還沒看出,那麼你對指標及記憶體的動態分配與釋放還需要再學習。
錯誤是發生在delete[]p,為什麼呢?按理說用new[]申請,用delete[]釋放,應該沒有問題啊。但是錯誤發生的原因是因為delete[]p釋放的是陣列num[100]的空間,而我們申請的空間根本就沒有釋放,為什麼會出現這種情況呢?因為此時的指標已指向了num陣列的首地址,而num[100]的空間會由系統自動釋放,而我們現在強行釋放,所以會發生錯誤。
②int *p=new int[3];
*p=1;
p++;//p的指向改變了,指向了下一空間
*p=2;
delete []p;
大家能發現這段程式碼有什麼問題嗎?
錯誤還是發生在delete[]p,c/c++規定,當刪除一個指標時,這個指標應指向其首地址,而上面的程式碼中p值已經發生了變化,所以會發生錯誤,如何避免呢?可以備份一份;如 int * pbak=p;在釋放的時候,用delete[]pbak即可。
③ int* p = new int(10);
int*pp=p;
delete[]p;
delete[]pp;
這段程式碼哪裡又發生了錯誤呢?(轉者:釋放了兩次)
我們要知道,p向作業系統申請了10個int型別的空間,而pp只是指向這個空間,作業系統並沒有為其再分配10個int型別的空間,所以當你用delete[]p釋放這個空間後,再用delete[]pp釋放就會發生錯誤。其實不管用哪個釋放,只要釋放一次就行了。
④ int a=100;
itn *p=&a;
delete p;
看到了這裡,如果你還不能看出這段程式碼的錯誤,那你前面的白看了,說明你還是沒有真正懂得啊!
錯誤還是發生在deletep,什麼原因?因為p並沒有通過new獲得記憶體空間,只是指向某個變數,而deletep是強行釋放a的空間,肯定發生錯誤啦。
3.delete與delete[]的區別
我們首先要知道當delete的時候,系統會自動呼叫已分配的物件的解構函式。
那麼當我們用new[]分配的物件是基本資料型別的時候,用delete和delete[]沒什麼區別,都可以。但是當用new[]分配的物件是自定義型別的時候,必須要用delete[],這樣它才會呼叫每個物件的解構函式,除非你的解構函式沒有做任何事。
總結一句話:使用 new得來的空間,用 delete來釋放;使用 new [] 得來的空間,必須用 delete []來釋放。這樣肯定不會錯。
相關文章
- 表連線時update與delete操作需注意的地方delete
- delete input 與 delete all inputdelete
- delete OBSOLETE 與 delete expirieddelete
- rman 中delete 與delete force 的區別delete
- drop、delete 與truncatedelete
- delete 和 delete [] 的真正區別delete
- backup archivelog delete input 與delete all input 區別Hivedelete
- truncate與delete的區別delete
- array new 與 array deletedelete
- deletedelete
- oracle truncate 與 delete 的區別Oracledelete
- QT父子與QT物件deleteQT物件delete
- delete 與全表掃描delete
- margin-top使用需要注意的地方
- /etc/fstab檔案需要注意的地方
- RMAN 中delete exipired 和 delete obsolete 的區別delete
- FormData delete()ORMdelete
- URLSearchParams delete()delete
- JavaScript deleteJavaScriptdelete
- DELETE STATISTICSdelete
- rman 中的 delete all input 和 delete input 的區別delete
- Javascript中的deleteJavaScriptdelete
- SQL truncate 、delete與drop區別SQLdelete
- APPEND載入與DELETE操作APPdelete
- delete與高水位線HWM回收delete
- js switch語句需要特別注意的地方JS
- link流程 建立時需要注意的地方
- 26個提升java效能需要注意的地方Java
- Struts中上傳檔案需要注意的地方
- javascript delete刪除屬性的注意點簡單介紹JavaScriptdelete
- zt_orafaq_delete與truncate的區別delete
- 一個關於c++字串處理和delete[]與delete差別的問題 (轉)C++字串delete
- springMVC的@ResponseBody、@RequestBody使用需要注意的地方SpringMVC
- oracle over()的使用和需要特別注意的地方Oracle
- MySQL Delete PHPMySqldeletePHP
- WeakMap delete() 方法delete
- WeakSet delete() 方法delete
- Map delete() 方法delete