目录
1.野指针
野指针指的是,所使用得到指针指向的是未知的、随机的、不正确的,这样的指针被使用后很容易造成越界访问。
1.1野指针的成因
1.1.1初始化指针时没有给出明确地址
int* a ;
若写出这样的指针,那么这就是个野指针。在初始化时,并没有把此指针置为空指针NULL;
也没有指向某个明确的地址。
1.1.2指针所指向空间已被释放
int* test() { int a = 100; // 在这里创建了变量a,并且这个函数返回的值就是这个a的地址 return &a; } int main() { int *ptr = test(); // 这里用ptr指针变量来接受test函数返回的地址 return 0; }
可以通过这段代码来解释这个错误:
当在函数中创建变量a后,a的地址中确实存在着100这个数,但是当test函数运行完后,变量a被系统回收,那么这个地址内就不再存在着100,可能指向着任何内容,此时把这个地址返回给主函数中的ptr,这是一个很危险的行为。
1.1.3指针的越界访问
#include<stdio.h> int main() { int arr[5] = { 0 }; int* p = &arr; for (int i = 0; i < 6; i++) { *(p + i) = i; } return 0; }
通过这段代码可以发现,创建的数组只有5个整型单位的长度,但是在for循环中,i的循环次数来到了6次,这样就会让p越界访问,超过了数组的长度。
1.2如何避免空指针
1.2.1初始化有明确去向
当在创建指针变量时,明确地将此指针指向自己所需要的空间,若暂时用不到,务必要将其置为NULL空指针。
1.2.2当用完此指针变量时,也要置为NULL空指针
当运用完一个指针变量时,即时把此指针置为NULL空指针,以防影响后续的指针运用。
1.2.3assert断言
在C语言中,有语句assert,需要带有头文件<assert.h>
int * a = NULL;
assert(a);
当在代码中使用assert断言时,系统会辨别assert内表达式的真假,如果为真,那么就继续运行,如果为假,那么在编译运行时就会报错并且指出位置。
我们可以通过这个语句,在每次使用指针前来确定此指针是否为空指针。
2.指针在一维数组中的理解
2.1一维数组名的理解
数组名代表着什么?
int main() { int arr[10] = { 1 }; int* s = &arr[0]; int* sl = arr; printf("%d \n", *s); printf("%d \n", *sl); return 0; }
可以通过运行结果看出,两个指针变量指向的分别是,&arr[0] 和 arr , 但打印出的是同结果,那么我们是否可以推测:数组名就代表着数组中首元素的地址呢?
我们可以通过调试来证实一下:
证实了我们的猜测是正确的。
2.2数组名的两个特殊搭配
2.2.1sizeof(数组名)
当使用sizeof(数组名)时,此时的数组名代表着什么呢?
int main() { int arr[10] = { 1 ,2,3,4,5,6,7,8 }; int a = sizeof(arr); printf("%d", a); return 0; }
可以看出此时sizeof算出的是整个数组中总元素的总大小,所以此时的数组名代表着的就是整个数组。
2.2.2&数组名
当对数组名取地址时,取到的地址是什么呢?
从这张图看出似乎还是首元素的地址,但此地址并非首元素的地址。
此时的地址其实是整个数组的地址,但是这个地址的起始处也是首元素,所以才会和首元素地址相同。这两个地址虽然地址相同,但是还是有区别的。
这里我们通过地址+整数来体现他们的区别:
int main() { int arr[10] = { 1 ,2,3,4,5,6,7,8 }; int* a = &arr; int* b = &arr+1; int* c = &arr[0]; int* d = &arr[0]+1; printf("%p\n", a); printf("%p\n", b); printf("%p\n", c); printf("%p\n", d); return 0; }
可以看出,对数组名取地址再+1,地址向后走了8个int的长度,但是对首元素地址+1,地址向后走了一个int的长度。
2.3一维数组传参的本质
我们已经知道了一维数组名代表的就是首元素的地址,那么我们在对数组进行传参的时候,可以直接传数组名也可以传首元素的地址,都是可行的。
#include <stdio.h>
void test(int arr[])
{
int sz2 = sizeof(arr)/sizeof(arr[0]);
printf("sz2 = %d\n", sz2);
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz1 = sizeof(arr)/sizeof(arr[0]);
printf("sz1 = %d\n", sz1);
test(arr);
return 0;
}
3.感谢查阅
会继续进行更新,感谢大家的阅读。