野指针

一、野指针

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。

#include <stdio.h>
int main(void)
{
            int *p;//当前的p就是野指针
            *p=4;
//报错 运行时的段错误,由野指针造成
} 

二、野指针出现的三种情况

1. 指向不可访问的地址:比如内核空间(每个进程都认为自己有4G的运行空间,但进程是共享4G空间,在每个进程可以寻址的范围内有一部分是操作系统的空间),结果是触发段错误。
2. 指向一个可用的且没有特别意义的空间:比如曾经使用过但无用的在栈、堆空间,结果是没有报错,但是有很大的隐患。
3. 指向了一个可用的空间,但这个空间在程序中正在被使用:比如是程序的一个变量,那么这个野指针的解引用会刚好修改这个变量的值,导致变量被莫名其妙的改变,导致程序出现离奇多的错误,最终程序崩溃或者数据被损害,这种危害最大的情况。

为什么加了printf函数后野指针就只可能发生后两种情况呢

因为printf函数是一个复杂函数,不停的申请栈,栈使用完没有被擦除。
指针变量如果是局部变量则分配在栈上,反复使用不会被擦除,所以是脏的。栈的使用多少会影响默认值,因此野指针的值是有一定规律不是完全随机。

三、如何避免野指针

指针没有明确的指向一个可用的内存空间,然后去解引用导致了野指针。
在指针的解引用之前确保指针指向一个绝对可用的空间,能够避免野指针。
1. 定义指针时同时初始化为NULL。
2 . 在指针解引用之前,先去判断这个指针是不是NULL。
3. 在指针使用完之后,将其赋值为NULL。
4. 在指针使用之前将其赋值绑定给一个可用地址空间。

#include <stdio.h>
int main(void)
{
            int a;
            int *p=NULL;
            int *p=&a;
           //中间省略400行.......
            if (NULL !=P)
            {
                  *P=4;
             }
            p=NULL;//使用完后将指针重新定义为NULL
}

实践中的处理方法,在中小型程序中不必严格参照这个标准,但在大型程序中建议严格参考这个原则。

NULL究竟是个什么

NULL在c中定义为:

#ifdef _cplusplus
#define NULL 0//在c++中NULL就是0
#else
#define NULL (void *)0//在c中NULL是强制类型转化为(void *)的0
#endif

在c中int *p;你可以p=(int *)0,但不可以p=0,因为c严格要求类型相同。
NULL的实质就是0,将指针赋初值给NULL,其实就是将指针指向0地址处。原因有两个:
1. 0地址是一个特殊地址,我们认为指针指向这个地址的为野指针。
2. 这个地址在一般的操作系统中都是不可被访问的,如果没按规章处理就会触发段错误,触发段错误已经是野指针造成的最小错误了。

判断野指针语句

写成 if (NULL != P),而不是写成if (p != NULL)
原因是如果NULL写在后面当中间是==号时容易写出=运算符,编译器不会报错,错误很难检查出来。所以一般把NULL写在运算符前面。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,876评论 1 32
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 8,755评论 0 6
  • 生老病死有时尽,秋枯春荣总不休。 因果循环几不爽?善恶分明为缘由。
    魇客阅读 1,571评论 0 6
  • 01 | 分手当天 你结束了一天的工作,刚刚到家,他坐在客厅等着你,说要跟你聊聊。 你有点惊讶,因为你们已经很长一...
    九公子lieb阅读 5,305评论 2 3
  • ​火箭在昨日哈登大爆发狂砍56分战胜爵士,之后三天火箭都没有比赛,队员也可以得到一定的时间放松休息,毕竟在NBA如...
    体育订阅阅读 1,639评论 0 0

友情链接更多精彩内容