4.7 指针和自由存储空间
指针是一个变量,其存储的是值的地址,而不是值本身。我们先看一看如何找到常规变量的地址。只需对变量应用地址运算符(&),就可以获得它的位置;例如,如果home是一个变量,则&home是它的地址。
程序清单4.14演示了这个运算符的用法。
程序清单4.14 address.cpp
#include<climits>
#include<string>
using namespace std;
int main()
{
int donuts = 6;
double cups = 4.5;
cout << "and donuts adress = " << &donuts << endl;
cout << "cups value = " << cups;
cout << "and cups adress = " << &cups << endl;
system("pause");
return 0;
}
C++采用的方法是,使用关键字new请求正确数量的内存以及使用指针来跟踪新分配的内存的位置
指针用于存储值的地址。因此,指针名表示的是地址。*运算符被称为间接值(indirect velue)或解除引用(dereferencing)运算符,将其应用于指针,可以得到该地址处存储的值(这和乘法使用的符号相同;C++根据上下文来确定所指的是乘法还是解除引用)。例如,假设manly是一个指针,则manly表示的是一个地址,而*manly表示存储在该地址处的值。*manly与常规int变量等效。程序清单4.15说明了这几点,它还演示了如何声明指针。
程序清单4.15 pointer.cpp
#include<climits>
#include<string>
using namespace std;
int main()
{
int updates = 6;
int * p_updates;
cout << endl << "*p_updates = " << *p_updates << endl;
cout << "p_updates = " << p_updates << endl;
cout << "Now updates = " << updates << endl;
system("pause");
return 0;
}
从中可知,int变量updates和指针变量p_updates只不过是同一枚硬币的两面。变量updates表示值,并使用&运算符来获得地址;而变量p_updates表示地址,并使用*运算符来获得值(参见图4.8)。由于p_updates指向updates,因此*p_updates和updates完全等价。可以像使用int变量那样使用*p_updates。正如程序清单4.15表明的,甚至可以将值赋给*p_updates。这样做将修改指向的值,即updates。
4.7.1 声明和初始化指针
顺便说一句,*运算符两边的空格是可选的。传统上,C程序员使用这种格式:
int *ptr;
这强调*ptr是一个int类型的值。而很多C++程序员使用这种格式:
int* ptr;
这强调的是:int*是一种类型—指向int的指针。在哪里添加空格对于编译器来说没有任何区别
使用new来分配内存
int *pn=new int;
使用delete释放内存
这将释放ps指向的内存,但不会删除指针ps本身。
只能用delete来释放使用new分配的内存。然而,对空指针使用delete是安全的。
4.7.6 使用new来创建动态数组
不管程序最终是否使用数组,数组都在那里,它占用了内存。在编译时给数组分配内存被称为静态联编(static binding),意味着数组是在编译时加入到程序中的。但使用new时,如果在运行阶段需要数组,则创建它;如果不需要,则不创建。还可以在程序运行时选择数组的长度。这被称为动态联编(dynamic binding),意味着数组是在程序运行时创建的。这种数组叫作动态数组(dynamic array)。使用静态联编时,必须在编写程序时指定数组的长度;使用动态联编时,程序将在运行时确定数组的长度。
使用new创建动态数组
int * pso=new int[10];
new运算符返回第一个元素的地址。在这个例子中,该地址被赋给指针psome。
对于使用new创建的数组,应使用另一种格式的delete来释放:
delete [] pso;
- 不要使用delete来释放不是new分配的内存。
- 不要使用delete释放同一个内存块两次。
- 如果使用new [ ]为数组分配内存,则应使用delete [ ]来释放。
- 如果使用new [ ]为一个实体分配内存,则应使用delete(没有方括号)来释放。
- 对空指针应用delete是安全的。
- 程序清单演示了如何使用new来创建动态数组以及使用数组表示法来访问元素;它还指出了指针和真正的数组名之间的根本差别。
-
#include<iostream>
using namespace std;
int main()
{
double * p3 = new double[3];
p3[0] = 0.2;
p3[1] = 0.5;
p3[2] = 0.8;
cout << "p3[1]=" << p3[1] << endl;
p3 = p3 + 1;
cout << "Now p3[0] is " << p3[0] << endl;
cout << "p3[1]" << p3[1] << endl;
p3 = p3 - 1;
delete [] p3;
system("pause");
return 0;}结果如下: