指针赋予了C++语言对内存更大的控制权,用不好也会导致内存泄漏等问题。先过一遍指针的基本知识。
首先要理解指针是什么?它是一种特殊的变量(指针就是指针变量的简便表示),和char,float是类似的。不过它存储的是数据的地址。
同样指针需要声明和初始化;
int * ptr;
ptr==&a (a是一个int变量)
先看第一句,int* 代表是一个指向int 类型数据的指针变量,double*就是指向double类型数据的指针变量。这里我们需要分辨一个概念,就是指针变量本身大小是固定的,都是四字节(对于32位计算机),前面的int ,double指的是它保存的地址所对应的数据长度,这样在寻址时就知道需要多少字节的长度。
指针还有一个很重要运算符就是解除引用*
cout<<*ptr 就是显示a的值。
这就是指针基本的三种操作。
这里还需要注意一点,就是解除引用之前指针必须初始化,因为声明一个指针变量时,计算机会分配一个存储地址的内存,但不会分配指针指向那个数据的内存;举个例子
int * ptr;
*ptr=10;
这里ptr不知道指向哪里,但是后面又给指向地方重新赋值为10了。那么10会赋值到哪里呢?不知道,可能有任何值。这将导致一些很难追踪的bug。
new和delete
前面提到的指针似乎就是使数据有另一种访问的方式(解除引用访问),其实指针真正用武之地就在于运行阶段分配未命名的内存可以存储值。而运行阶段就是用new
int *pn=new int ;
这句话就是,程序需要一个int长度的内存,然后计算机找到后把地址返回给pn。
当然,new可以创建动态数组。
int *pn=new int [size];
众所周知,new必须有delete对应。不能不delete,不能重复delete两次。否则会内存泄漏。
**内存泄漏:**我们要知道new分配的空间是在堆上的,它不会随着函数或者程序结束而结束,如果忘记delete,那么当函数结束时,指向该内存区域的指针已经消失了,但是堆上的空间还存在,我们已经无法访问这些空间了,因为指针已经失效了。C++11中智能指针可以解决这种问题。
指针和数组
在C++中,数组名视为数组第一个元素的地址。
int taco[5]={1,2,3,4,5};
那么,tacos就是数组第一个元素的地址,即tacos=1,
指针算术也是一个重要的概念。(tacos+1)=2,这里加1指的是加4个字节,即转移到第二个元素的地址,再解除引用。
大多数情况下,两种方式是等价的,但有两种特殊情况。
1、sizeof(数组名)是数组的长度,sizeod(指针)是指针的长度。
2、tacos,&tacos两个的地址相同但意义不同,后者指的是整个数组的地址。
前者相当于 int * ptr=tacos,
而后者相当于 int(*ptr)[5]=&tacos,这是一个数组指针,如果去掉括号,就是一个指针数组。