1. 程式人生 > >new 一定要與 delete 配合使用嗎?

new 一定要與 delete 配合使用嗎?

new和delete

我們在程式設計時一般要new和delete配合使用,否則會引起記憶體洩露,請看下面這個程式:

  1. #include <iostream>
  2. #include <windows.h>
  3. using namespace std;
  4. void fun1(int *&p)
  5. {
  6.     int i = 10;
  7.     p = &i;
  8.     cout<<i<<" "<<&i<<endl;
  9. }
  10. int main()
  11. {
  12.     int *= new
     int();
  13.     cout<<*p<<" "<<p<<endl;
  14.     fun1(p);
  15.     cout<<*p<<" "<<p<<endl;
  16.     Sleep(1000);
  17.     cout<<*p<<" "<<p<<endl;
  18.     //delete p;
  19.     return 0;
  20. }

執行結果如下:

0               003B33A0

10            0012FE6C

10            0012FE6C

1000        0012FE6C

首先分析一下上面程式的結果,在new了一個int型別的資料後,返回地址給p。(由於new int後面有一個括號,表示初始化內容為0,所以*p為0,p為003B33A0)

然後呼叫func1,形參為實參的引用,所以其實就是p。將p指向i以後,即將p的值修改為i的地址,而*p即為i。所以第二行和第三行輸出結果一樣,到此為止比較容易理解。

最後問題出來了,在sleep(1000)以後,為什麼p的值發生修改了呢?

其實原因是在func1中i是區域性變數,在func1執行完畢後,i需要釋放,那麼釋放到底是什麼意思呢?

其實釋放就是將變數i對應的內容銷燬,標記為未使用狀態,那麼以後程式可以繼續使用這塊記憶體。既然i的內容已經銷燬,那麼*p的內容也變為不可知的狀態,所以在sleep(1000)以後,系統已經將i釋放,此刻p依然指向i,但i的內容已經變為不可知狀態,在程式中變為1000。而在剛執行完fun1(p)的時候系統還未來得及釋放i,所以依然保持10。

好了,問題又來了,注意我在最後把delete p給註釋掉了,肯定有人會以為這樣會造成記憶體洩露,其實當初我也是這麼認為的,當把delete p加上以後,程式在執行到最後,會出現一個警告。


想來想去,其實此時已經完全沒有必要delete了,因為系統釋放i的時候相當於已經執行了delete p的操作,因為i的內容被釋放,而p又指向i,當然p也同時被釋放。

這時候又有疑問了,既然p已經在func1之後完畢後被釋放了,那最後為什麼還能輸出p和*p呢?

因為delete p的操作,其實就是將*p的內容銷燬,p的值依然保持不變,所以依然可以在delete p以後使用p。

不信的話可以將上述程式稍微修改一下:

  1. #include <iostream>
  2. #include <windows.h>
  3. using namespace std;
  4. void fun1(int *&p)
  5. {
  6.     int i = 10;
  7.     p = &i;
  8.     cout<<i<<" "<<&i<<endl;
  9. }
  10. int main()
  11. {
  12.     int *= new int();
  13.     cout<<*p<<" "<<p<<endl;
  14.     //fun1(p);
  15.     cout<<*p<<" "<<p<<endl;
  16.     Sleep(1000);
  17.     delete p;
  18.     cout<<*p<<" "<<p<<endl;
  19.     return 0;
  20. }

執行結果如下:

0                         003B33A0

0                         003B33A0

-572662307      003B33A0

可見,在delete p執行以後,p的值並沒有發生變化,只是p所指向的內容被銷燬,變為不可知狀態。

最後,總結一下,new操作一定要配合一個delete操作,但delete不一定是顯式的呼叫,可以由系統幫助完成。而delete p其實只是銷燬內容,即*p,而p本身的值卻並沒有發生變化。