1. 指针与堆
1.1 指针的三大用途
- 处理堆中存放的大型数据;
- 快速访问类的成员数据和函数;
- 以别名的方式向函数传递参数;
注:指针可以通过内存地址直接访问数据,可避免在程序中复制大量代码,因此指针的效率高。一般来说,写程序就是与数据打交道,在执行程序某一功能时,将该功能所需的数据加载到内存中,然后在执行完毕时释放内存。
1.2 指针在堆中空间的操作
用指针创建堆中空间,关键字new。在C++中使用关键字new创建一个堆并分配内存;
(1)用指针创建堆中空间:int *p = new int; (2)在该指针指向的地址处存放一个值1:*p = 1;
注:为了保持数据的隐密性,堆中的每个内存单元都是匿名的,因此必须先在堆中申请一个内存单元地址,然后把它保存到一个指针中,这样只有使用该指针才可访问到该内存单元的数据。
用指针删除堆中空间,关键字delete。在C++中,假如你不需要一块内存空间,就必须对指向它的指针使用关键字delete;
(1)用delete释放指针在堆中创建的空间: int *p = new int; delete p; //这里将释放指针所指向的内存,而不会释放指针,因此还可以使用该指针 p = new int;//对指针p重新赋值,让其指向新的内存空间 delete p;//释放新申请的空间,这是安全的</font> (2)但以下情况绝对注意,不要再次对该指针进行删除,会导致程序崩溃,而且难排查: int *p = new int; delete p; delete p;=>请不要再次对该指针进行删除,因为它所指向的内存区域已经被释放,如果再进行释放,将会使程序崩溃。
有效防止再次释放导致的程序崩溃,可以做以下处理:
(1)正确的释放内存空间处理,用delete释放指针创建的堆中空间后,将指针置为空指针(赋0或NULL): int *p = new int; delete p; p = 0; //置为空指针,避免不小心再次释放导致程序崩溃 delete p; //删除一个空指针是安全的
注:当用delete释放一个指针所指向的空间后,最好将该指针中保持的内存地址清0(即置为空指针),以免重复操作该地址导致程序崩溃。
1.3 内存泄漏的概念
内存泄漏: 就是假如没有释放掉指针指向的那块内存空间,就对指针重新赋值,使其指向另一块内存空间,导致之前开辟的内存空间无法被使用。
(1)错误例子: int *p = new int; p = new int;//导致前一个所开辟的那块内存空间无法使用
(2)正确例子: int *p = new int; delete p;//先释放之前开辟的空间 p = new int;//在让指针指向另一块内存 delete p; p = 0;
注:在使用new在堆中申请了一块内存以后,假如不再使用那块内存空间,那么一定要delete释放它。
1.4 指针的运算
指针的加减运算:内存地址的自加或自减。
int *p = new int; p++;//内存地址自加 p--;//内存地址自减
指针的赋值运算:将一个指针变量地址赋值给另一个指针变量地址。
int *p = new int; int *p1 = new int; delete p;//释放p指向的内存空间,不然会造成内存泄漏 p = p1;//将指针p1保存的内存地址赋给p
指针的相减运算:得出地址差。
int *p = new int; int *p1 = new int; int size = p-p1;
指针的比较运算:即内存地址比较。
int *p = new int; int *p1 = new int; if (p > p1)//内存地址的比较 { return true; } else { return false; }
参考文献:
[1]《C++全方位学习》范磊——第八章
[2]《C++程序设计教程(第二版)》钱能——第三章
[3] 百度搜索关键字:C++指针、指针与堆、空指针、内存泄漏、指针的运算