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)自生自滅,不留痕跡,對記憶體不會造成影響,如顯示輸出函式 。