【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。

时间:2022-12-08 17:09:33

????write in front????   

????大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流????

????2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家博主 & 星级博主~掘金⇿InfoQ~51CTO创作者[新人创作榜No.11]~周榜393﹣总榜1024⇿全网访问量40w+????

????本文由 謓泽 原创 发布在51CTOP 如需转载还请通知⚠

????个人主页-​謓泽51Ctop的博客​????

????欢迎各位→点赞???? + 收藏⭐️ + 留言????

????系列专栏-​謓泽51Ctop的分类_51CTO博客​????

✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本????



【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。


???? 指针类型的意义(1)

指针类型的意义,代码如下所示↓

int a = 0x11223344;
int *pa = &a;
*pa = 0;

此时,经过调试阶段我们可以发现,首先 a 的地址赋值给指针变量并且对象类型是 int 类型。然后,再通过 解引用 *pa 把原来 &a 的地址变成0,那么通过这个现象,我们就可以知道用int * 进行解引用的话,我们是成功访问到 ④个字节 的地址。是不是可以说明指针访问字节是个字节呢。

【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。


【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。

int a = 0x11223344;
char *pa = &a;
*pa = 0;

经过调试阶段我们可以发现,首先 a 的地址赋值给 指针变量并且对象类型是 char 类型。然后,再通过 解引用 *pa 把原来 &a 的地址变成0。那么通过这个现象,我们就可以知道用char * 进行解引用的话,而我们是成功访问到 ①个字节 的地址。可以看出只是类型发生了变化,访问权限就会发生变化从这里说明了指针是只能访问个字节的,这是C语言语法标准规定死的

【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。


【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。


所以从上面两个不同指针对象,我们就可以从中发现。只是不同类型的变化,就可以在调试当中发现它们的访问权限就发生了变化这就从中说明指针类型是具有意义的

如果我是个整形指针(int*)的话,解引用的时候,我去访问一次的话。解引用一次就可以访问个字节。按照上面图中我就可以把个字节全部变成0了。

然而,如果我是一个字符指针(char*)的话。我解引用一次我就只能访问其中的个字节。

通过这个例子可以知道:不同类型指针在解引用的时候就决定它的访问权限有多大


???? 指针类型的意义(2) 

接下来,举出第②个例子。如下代码所示↓

#include<stdio.h>
int main(void)
{
int arr[10] = {0};
int *p = arr;
char *pc = arr;
printf("%p\n",p);
printf("%p\n",p+1);

printf("%p\n",pc);
printf("%p\n",pc+1);
return 0;
}

编译器运行结果如下↓

【C语言】指针类型的意义(1)、指针类型的意义(2)、野指针、如何规避野指针。


在第二行编译运行结果上,如果是我整形指针+1的话。我实际上的值+4

在第四行编译运行结果上,如果是我字符指针+1的话。我实际上的值+1

字符指针+1的话,相当于跳过了一个字符。那么跳过一个字符的话,我不就相当于+1

如果我是整形指针+1,相当于跳过一个整形。如果跳过一个整形,就相当于跳过4个字节。那其实就是相当于+4

那这个为什么会产生这样的不同呢?因为 p 以及 pc 的指针类型不同

那么从这个角度可以知道:指针类型决定了指针走一步就可以走多远,也就是步长


⚔ 野指针  

概念:野指针就是指针指向的位置是不可知的。

  1. 随机的
  2. 不正确的
  3. 没有明确的限制

指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的

指针越界也会导致野指针问题,这里解释下:就是当你指针指向的范围超过数组名范围时,那么那个指针就是野指针了


???? 如何规避野指针

指针的初始化,不光是指针也要初始化,其它的任何类型都需要初始化。

小心指针越界。

指针指向空间释放即使置NULL。

指针使用之前检查有效性。

示例代码如下 ↓

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main(void)
{
int *p = NULL;
*p = 20;
return 0;
}

在上述代码当中我们把指针变量p赋值给了空指针NULL,但是这里我们又把p进行解引用操作改变成了20,就相当于我们访问了NULL的地址。实际上NULL相当于是0,如果我们要访问0的地址的话它是不属于我们用户当中的,并没有分配给我们用户,所以当我们把20数字放进去的话是不能放进去的属于是非法访问了!

运行结果如下↓

0x002A1002 处有未经处理的异常(在 ConsoleApplication1.exe 中):  0xC0000005:  写入位置 0x00000000 时发生访问冲突。