1. 程式人生 > >C++語言中用指標申請記憶體時產生的問題。

C++語言中用指標申請記憶體時產生的問題。

看下面一段程式:
#include<iostream.h>
int main()
{
        int *p;                 //(1)
        {
              int   *tm;        //(2)
              tm=new  int;      //(3)
              *tm=20;           //(4)
              p=tm;             //(5)
        }                      //(6)
   
         return  0;
}

程式執行到(1)時p=0xcccccccc,*p=error,
程式執行到(2)時tm=0xcccccccc,*tm=error,
程式執行到(3)時tm=0x43150653,*tm=error,
程式執行到(4)時tm=0x43150653,*tm=20,
程式執行到(5)時p=0x43150653,*p=20,
程式執行到(6)時p=0x43150653,*p=20,tm=error,*tm=error,


執行到(6)時tm被釋放,但利用tm申請的記憶體空間並沒有被釋放,在本例項中利用p指標記錄了tm所申請的記憶體空間的地址,如果沒有定義p和p=tm;語句的話,右 } 到來時tm被釋放,tm所申請的記憶體並沒有被釋放,並且失去了控制這段記憶體的把柄,這是相當危險的,並且是隱蔽的。在很多情況下如果不手動刪除所申請的記憶體,便會產生記憶體溢位的後果,請看下面程式:
int main()
{
     int *p;
     {
        for(int  i=0;i<99999999;i++)
              p=new  int;
     }
}

可以通過資源管理器察看記憶體使用情況,在區域性程式碼結束時程式自動釋放的是指標的那4個位元組,而不是指標所指向的記憶體,也就是說指標不在了,但記憶體還在!

這就是為什麼在Windows API中 hdc=GetDC(hwnd); 後必須呼叫RleaseDC(hwnd,hdc); GetDC是通過定義了一個指標申請了一塊記憶體,把這塊記憶體的地址交付外界,即傳給hdc,要不然GetDC結束後這段記憶體就釋放了,所以用完後,還要呼叫RleaseDC.  

如此API函式可以分為如下幾種:
(1). 用指標開闢記憶體,把指向這段記憶體的指標交付外界,函式結束時不釋放記憶體。
(2)不管用什麼方式開闢記憶體,把記憶體的一個拷貝給外界,函式結束時釋放記憶體。如BebinPaint(hwnd,&ps),GetFontMetrics(&lf),其中的ps,lf必須是外界定義好的且已經開闢好記憶體空間了的,函式把ps,lf的一份拷貝給ps,lf.
(3)自生自滅,不留痕跡,對記憶體不會造成影響,如顯示輸出函式 。