常见的野指针问题
- 指针变量没有被初始化。任何指针变量在刚被创建的时候不会自动成为NULL指针,它的缺省值是随机的。所以指针变量在创建的时候,要么设置为NULL,要么指向合法的内存。
- 指针p被free/delete之后,没有被置为NULL(最好加一句p = NULL;)。他们只是把指针指向的内存给释放掉,并没有把指针自身内容释放。
- 指针操作超越了变量的作用范围。不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。
指针和引用的区别
- 引用必须被初始化,指针不必(但不推荐)。
- 引用初始化以后不能被改变,指针可以改变所指的对象。(1.2有联系)
- 引用不是一个对象,所以它没有实际的地址。指针是一个对象,它有实际的地址,所以我们可以定义指向指针的指针,但是绝对不能定义指向引用的指针。
- 不存在指向空值的引用,但是存在指向空值的指针。(3.4有联系)
关于引用
引用是变量的别名,总是指向在初始化时被指定的对象,实现了对所指向对象的间接访问。
我们通过在变量名前添加&来定义一个引用类型。例如:
int val = 10;
int tmp = 15;
int &refVal = val; //引用初始化
refVal = 20; //其实这个赋值操作真正的作用对象是val,val=20
refVal = tmp; //其实是把tmp的值赋值给val,val = 15,此时refVal指向地址依旧不改变,依旧为val的别名
double &refVal2 = val; //错误,类型不匹配
int &ref = 10; //错误,不能与字面值进行绑定
关于指针
指针指向对象的地址,用内存来保存对象的地址,实现了对所指向对象的间接访问。
我们通过在变量名前添加*来定义一个指针类型。例如:
int val = 10;
double dval = 15.0;
int *p;
p = &val; //将val变量的地址保存在p指针中
p = &dval; //错误,类型不匹配
*p = 20; //此时是将val的值赋为20
int *p1 = 0; //定义一个空指针
int *p2 = nullptr; //等价于上面的语句
int *p3 = NULL; //同样是定义一个空指针,需要在代码中加入#include <cstdlib>
int **pp = &p; //指向指针的指针,pp指向p的地址,p指向val的地址,注意声明符的写法
//但是我们需要注意,不能直接将变量的值赋给一个指针,哪怕该变量的值等于0也不可以
int tmp = 0;
int *p4 = tmp; //错误