指针和自由存储空间

计算机程序在存储数据时必须跟踪的3种基本属性:

  • 信息存储在何处
  • 存储的值为多少
  • 存储的信息是什么类型
对变量使用地址运算符(&),就可以获得它的位置
*运算符被称为间接值(indirect value)或解除引用(dereferencing)运算符,将其应用于指针,可以得到该地址处存储的值
声明和初始化指针 下面的声明创建一个指针(p1)和一个int变量(p2):
int* p1, p2;

对每个指针变量名,都需要使用一个*
指针的危险 在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。
一定要在指针应用解除引用运算符*之前,将指针初始化为一个确定的、适当的地址。
指针和数字
  • 不能简单地将整数赋给指针:
int * pt; pt = 0xB8000000; // type mismatch

  • 应通过强制类型转换将数字转换为适当的地址类型:
int * pt; pt = (int *) 0xB8000000; // types now match

使用new来分配内存 指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。
new将找到一个长度正确的内存块,并返回该内存块的地址。
int * pn = new int;

new分配的内存块通常与常规变量声明分配的内存块不同。变量nights和pd的值都存储在被称为栈(stack)的内存区域中,而new从被称为堆(heap)或自由存储区(free store)的内存区域分配内存。
使用delete释放内存 使用delete时,后面要加上指向内存块的指针(这些内存块最初是用new分配的):
int * ps = new int; // allocate memory with new . . . delete ps; // free memory with delete when done

这将释放ps指向的内存,但不会删除指针ps本身。一定要配对地使用new和delete;否则将发生内存泄漏(memory leak)。
不要尝试释放已经释放的内存块;不能使用delete来释放声明变量所获得的内存。
只能用delete来释放使用new分配的内存。然而,对空指针使用delete是安全的。
使用new来创建动态数组 通常,对于大型数据(如数组,字符串和结构),应使用new。
  • 使用new创建动态数组
int * psome = new int [10]; // get a block of 10 ints ... delete [] psome; // free a dynamic array

new运算符返回第一个元素的地址。
方括号告诉程序,应释放整个数组,而不仅仅是指针指向的元素。
使用new和delete时,应遵守以下规则。
1.不要使用delete来释放不是new分配的内存。
2.不要使用delete释放同一个内存块两次。
3.如果使用new []为数组分配内存,则应使用delete []来释放。
4.如果使用new []为一个实体分配内存,则应使用delete(没有方括号)来释放。
5.对空指针应用delete是安全的。
使用动态数组 数组和指针基本等价是C和C++的优点之一。
只要把指针当数组名使用即可。
将指针加1后,它将指向下一个元素。
psome = psome + 1; //psome[0]现在指的是数组的第2个值

double wages[3] = {10000.0, 20000.0, 30000.0}; //和所有数组一样,wages也存在下面的等式 wages = &wages[0] = address of first element of array

将指针变量加1后,其增加的值等于指向的类型占用的字节数。
arrayname[i] becomes *(arrayname + i) pointername[i] becomes *(pointername + i)

在很多情况下,可以相同的方式使用指针名和数组名。对于它们,可以使用数组方括号表示法,也可以使用解除引用运算符(*)。在多数表达式中,它们都表示地址。区别之一是,可以修改指针的值,而数组名是常量。
另一个区别是,对数组应用sizeof运算符得到的是数组的长度,而对指针应用sizeof得到的是指针的长度
【指针和自由存储空间】在C++中,用引号括起的字符串像数组名一样,也是第一个元素的地址

    推荐阅读