我们先来看段代码:
void Demo()
{
int *p=new int; //##1
*p=2; //##2
return; //##3
}
先看##1这行,意思是为指针p和int值分配存储空间,保存地址。看下面的图:
指针p | 0x44444e |
p的地址 | 0x77777a |
(无) | |
地址 | 0x44444e |
再看##2这行,意思是将值(也就是2)复制到动态内存中。看下图:
指针p | 0x44444e |
p的地址 | 0x77777a |
(无) | 2 |
地址 | 0x44444e |
这行代码的意思很好理解,就是把2这个数放在它该放的位置,这个时候*p也就有值了,即*p==2.
最后看##3这行,相信大家也注意到我给出的这段代码是一个函数,当函数被调用完毕后,指针p会发生什么呢?是的,p会被删除。那我们申请的那块大小为sizeof(int)的内存呢,它会被删除么?答案是没有。也就是这个函数被调用完毕后,内存区会保留这块int变量。大家想想,如果这个函数被调用很多次会出现什么后果,是的,内存泄漏。这是我们不愿意看见的Bug。
那么问题来了,如何避免呢?有两个办法:
第一个:在return;句前面加delete p;就可以了。很好理解,不多说了。但是这个办法有时也有它的弊端,这里我引用<<C++ Primer Plus>>这本书的一个例子,代码如下:
void reDemo(string &str)
{
string *p=new string(str);
........此处代码省略;
if(werid_thing())
throw exception;
delete p;
return ;
}
第二个:这里要介绍下C++11的智能指针了。一共有三个指针模板:auto_ptr,unique_ptr和shared_ptr。其中auto_ptr是C++98的,后面两个是C++11的。用法如下:
void Demo()
{
auto_ptr<int> p(new int);
*p=2;
return;
}
这三个指针各有千秋,关于在何时分别使用它们,内容较多,我就不演示了。建议读者百度它们的详细的介绍或者是<<C++ Primer Plus>>这本书,第六版上的第16章,667页上的内容。这本书讲的很详细,同时也是很赞的一本入门C++的经典书!
最后结尾再给大家看一段代码:
int main()
{
int *a;
*a=10;
return 0;
}
大家想想这段代码放在编译器运行会不会有错呢?没错,如果你真的理解了我上面的代码,你的回答就是:会报错。下面我就就来解析一下。首先,申请一个int指针变量,然后。。。。。仔细看这段代码,你会发现其实10这个值在内存中是没有为它分配内存的,既然没有分配内存(这里也就是说没有new),何来指针指向它之说呢。