看下面一段程序:
#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)自生自灭,不留痕迹,对内存不会造成影响,如显示输出函数 。