指针的含义及使用方法
指针类型及使用方法
野指针的定义
野指针的成因及如何避免野指针
指针的定义:本质上是一个变量,用来存储地址的变量,因此,可以以形象的把地址称为指针,指针称为地址。
举例:
int a = 10;//在内存中开辟一块空间 int* p = &a; //对变量a,使用操作符&取它的地址 //将a的地址存放在变量p中,p是指针变量,用来存放地址的
小tips:一个单元的大小是一个字节,在32位平台上,一个指针变量(地址)的大小是4个字节,在64位平台上,一个指针变量(地址)的大小是8个字节。
指针和指针类型:
1:指针的大小:32位平台上指针的大小位4个字节,64位平台上指针的大小为8个字节。
代码如下所示:
printf("%d\n", sizeof(int*)); printf("%d\n", sizeof(char*)); printf("%d\n", sizeof(float*)); printf("%d\n", sizeof(double*)); printf("%d\n", sizeof(short*));
输出结果如下所示:
4 4 4 4
代码如下所示:
int a = 0x11223344; int* pa = &a; char* pc = &a; printf("%p\n", pa); printf("%p\n", pc);
输出结果如下所示:
通过上述所举的例子我们可以看出指针变量类型的不同并没有影响地址的存放,那么指针变量的类型是不是没有意义呢?答案肯定不是的,下面我们继续研究指针变量类型。
当指针变量和变量本身是同一种类型时:
int a = 0x11223344; int* pc = &a; printf("%p\n", *pc); *pc = 0; printf("%p\n", *pc);
输出结果如下所示:
当指针变量和变量本身不是同一种类型时:
int a = 0x11223344; char* pc = &a; printf("%p\n", *pc); *pc = 0; printf("%p\n", *pc);
输出结果如下所示:
通过对比上面两种情况,我们可以得出的结论是:**指针类型决定了指针进行解引用操作的时候,能够访问空间的大小,int*p: *p能够访问4个字节 char *p: *p能够访问1个字节 double p: p能够访问8个字节。
此外,指针的类型还决定了指针的步长(字节);int *p:p+1–>4 char *p:p+1–>1 double
*p:p+1–>8
举例:
int a = 0x11223344; int* pa = &a; char* pc = &a; printf("%p\n", pa); printf("%p\n", pa + 1); printf("%p\n", pc); printf("%p\n", pc+1);
输出如下:
那么这两个意义到底有什么作用呢?
举例说明:
int arr[10] = { 0 }; int* p = arr; int i = 0; for (i = 0; i < 10; i++) { *(p + i) = 1; printf("%d\n", arr[i]); }
输出结果如下所示:
当我们把指针变量的类型替换为char类型再来看代码运行情况。
int arr[10] = { 0 }; char* p = arr; int i = 0; for (i = 0; i < 10; i++) { *(p + i) = 1; printf("%d\n", arr[i]); }
输出结果如下所示:
因此在编译的时候我们可以通过实际情况去确定所需的指针变量类型。
野指针:
就是指指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
野指针成因:
1:指针未进行初始化
举例:
int* p;//局部变量不初始化,默认是随机值 int a;//局部的指针变量,就被初始化随机值 *p = 20;
2:指针越界访问:
举例:
int arr[10] = { 0 }; int* p = arr; int i = 0; for (i = 0; i <= 11; i++) { *(p++) = i;//随着p++的不断运行,当i越出了0-9这个范围,该指针就会变成野指针 }
3:指针指向的空间释放:
举例:
int main() { int* test(); int* p = test();//此时调用test函数把a的地址赋给指针变量p *p = 20;//该代码是想将p里面存放的a值改为20 //但是由于a的内存已经被释放,a变量现在的地址已经发生改变,无法实现改变变量的值 return 0; } int *test() { int a = 10;//a是一个局部变量,每次执行完该程序a的内存都会被释放,归还给系统 return &a;//每次返回的地址都是系统随机给的 }
那么如何避免野指针呢?
1:指针初始化
2:小心指针越界
3:指针指向空间释放即使置NULL
4:指针只用之前检查有效性