野指针与'关键字'NULL

一、NULL是什么?

  在C/C++中的标准定义:

#ifdef __cplusplus           //条件编译,判断是c++还是c环境
#define NULL 0 //c++环境
#else
#define NULL ((void *)0) //c语言环境
#endif
#endif

  在c语言中的NULL就被替换成了((void *)0),这个整体表示的是一个指针,即是指向0地址的viod类型的指针。

  所以我们可以理解为NULL的本质就是0,这个0要看做地址,即是0x00000000。

  NULL为什么出现,就得明白什么是野指针了。

注:虽然C标准没有说空指针与指向内存地址0的指针相同,但是分析之后是可以这样理解的。(NULL又称为空指针常量)  

二、野指针

1.什么是野指针

  又叫迷途指针,即指针指向的地址是随机的。(不指向任何合法的对象的指针)

2.野指针的出现

  指针变量在定义后,不去初始化。这个时候,值就是随机的。这时候这个指针变量就是野指针。

比如在栈里定义了一个指针变量,即栈给这个指针变量分配了一个内存,而这个内存里存的值就是该指针指向的地址,然而栈是脏的(反复使用,不擦除),并不知道地址里存的什么数,也就不知道指针指向了哪里。 

3.野指针的危害

指针变量在定义后,不去初始化,这个时候,值就是随机的,即指向了随机的一段内存。我们再去解引用时,就是去访问一个随机地址,那么会有什么样的后果也是未知的。

一般有三种情况:

①指向了不可访问的地址(系统不允许访问的地方)

  这种情况是最好的,因为程序会报段错误,无法执行。

②指向了可用的,暂时没有用到的地方(譬如程序没有用到的堆栈地址)

这种情况运行时没问题,也不会报错。但是实际上程序是有问题的,假如之后程序由于野指针出现了bug,就死活找不到原因了。

③指向了可用的,并且是程序中正在被使用的地方

这种情况野指针的解引用可能就会导致指向的那段内存的值被修改,出现一些离奇的错误,导致程序崩溃,数据破坏,损坏。    

打个比方:野指针就是个山贼,随机的抢劫过路商队。

  第一种情况就是

  (不可访问的地址)大型商队保镖太强,山贼(野指针)正准备抢劫就被干掉了,并向后面(我们)的商队发出了警告

  第二种情况就是

  (可以访问,暂时没用使用的地址)小型商队,山贼就直接抢了,暂时并不影响绕路的我们。

  第三种情况就是

  (程序正在使用)我们的商队,山贼可能抢的可能我们没法活下去(程序崩溃)

4.怎么去避免野指针

  在指针的解引用之前,一定确保指针指向一个绝对可用的空间。

  这时候NULL出现的很及时,常规做法

    ①定义指针后,将指针初始化为NULL。

    ②指针使用之前绑定一个可用地址。

    ③在指针解引用前,去判断是否为NULL。

    ④使用完,后赋值为NULL。

 int a = ;
int *p = NULL; //定义指针并初始化为NULL
p = &a; //绑定一个可用地址 if (NULL != p) //判断是否不等于NULL
{
*p = ; //解引用
} p = NULL; //使用完,重新赋值为NULL

注意(小技巧):

  一般将判断指针是否相等时,不写成if (p == NULL),而写成if (NULL == p),原因是== 与 = 的误错,程序的意思会不一样。等号少写后,if (p = NULL)不会报错,if (NULL = p)会报错。

三、NULL的作用

①让野指针指向一个 '安全的0地址处'

  大部分cpu中,内存0地址处不能随便访问的,所以避免野指针的误伤,指向0地址后的使用就会报段错误。帮助我们找错误。

②特殊标记,即增加程序的可读性。

  表示指针是个野指针。

四、各个零之间的区别('\0' '0' 0 NULL)

①'\0'是个转义字符,ASCII编码值是0,本质就是0.

  '\0'用法是C语言字符串的结尾标志

②'0'是个字符,ASCII编码值是48,即是48

  '0'是字符0,获取ASCII编码值

③0是数字0,本质也是0

  比较一个int类型的数字是否等于0,或者给变量赋值。

④NULL是个表达式((void *)0),强制转换为void * 的0,本质也是0

  用来比较指针是否是一个野指针


作者:Devil-wei

出处:https://www.cnblogs.com/Devil-wei/

版权声明:本文版权归作者,转载请标注文章作者与出处

野指针与'关键字'NULL的更多相关文章

  1. 关于空指针NULL、野指针、通用指针 (转)

    reference:https://www.cnblogs.com/losesea/archive/2012/11/16/2772590.html 首先说一下什么是指针,只要明白了指针的含义,你就明白 ...

  2. NULL指针、零指针、野指针

    1.1.空指针 如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17;p=(void*)0; 中的任何一种赋值操作之后, p 都成 ...

  3. 野指针、NULL指针和void*

    一.野指针 “野指针”不是NULL指针,是指向“垃圾”内存的指针. “野指针”的成因主要有三种: (1)指针变量没有被初始化.任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱 ...

  4. 关于空指针NULL、野指针、通用指针

    http://www.cnblogs.com/losesea/archive/2012/11/16/2772590.html 首先说一下什么是指针,只要明白了指针的含义,你就明白null的含义了.假设 ...

  5. 浅谈 “空指针、野指针、void*”

            Author: JW. Zhou Date: 2014/7/2 一.空指针(0/NULL) 返回NULL和返回0是完全等价的,因为NULL和0都表示空指针,换句话说:空指针是什么,就是 ...

  6. C语言 野指针与空指针

    //野指针与空指针的区别 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> //野指针是 ...

  7. 李洪强iOS开发之【Objective-C】09-空指针和野指针

    一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...

  8. 【Objective-C】4-空指针和野指针

    一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...

  9. c/c++:内存泄露和野指针的概念

    内存泄漏 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元.直到程序结束.即所谓内存泄漏.    注意:内存泄漏是指堆内存的泄漏. 简单的说就是申请了一块内存空间,使用 ...

随机推荐

  1. 如何修复使用WSUS进行升级Win 10 更新1809的报错(0x8024200)

    备注:该文档有另一个姊妹篇,介绍如何修复下游服务器一直有处于需要文件下载的状况. /* Style Definitions */ table.MsoNormalTable {mso-style-nam ...

  2. Windows Server 2016-启用默认Windows搜索服务

    当我们使用Windows Server 2016尝试从开始菜单或基于Windows Server 2016的计算机上的Cortana 搜索时,我们不会收到任何结果或不一致的结果. 原因 默认情况下, ...

  3. ios11苹果手机怎么投屏到电脑

    使用过苹果手机的用户都知道,苹果手机触摸屏操作极为流畅,网页浏览也非常轻松,各种网络上的应用可以说是非常完美.iPhone的娱乐功能相当的强大,能让苹果iPhone超越了其他手机很大的距离.但是手机怎 ...

  4. JAVA中AWT编程

    JAVA使用AWT和Swing 类完成图形用户界面编程,AWT全称是抽象窗口工具集(Abstract Window Toolkit),它是最早的sun提供的GUI库(Graphics User Int ...

  5. Unity User Group深圳站——Timeline & Cinemachine分享

    报名说明:UUG深圳站,2月分享活动正式启动,1月29日中午12:00前报名可获赠Unity精美纪念礼物一份~ 关于Unity Unity 是一款多平台的综合型游戏开发工具,它的出现对蓬勃发展的全球游 ...

  6. .NET Core 2.1来了!

    太棒了! .NET Core 2.0正式发布至今已经过去了大半年,这大半年说长不长说短不短,这段时间里,我是充分地体会到了微软的诚意,那就是认认真真打造一个优秀的开源平台.这大半年的时间里,微软一直在 ...

  7. 《ECMAScript6入门》___阮一峰 笔记

    let和const命令 let命令 循环体的let变量只对花括号作用域可见,花括号外不可见 循环体的语句部分是一个父作用域,而循环体内部是一个单独的子作用域 let声明的变量不存在变量提升,未声明的使 ...

  8. 视频直播 object 标签属性详解

    最近在做视频直播这一块的,html5的video不能实现此功能,在网上查找了资料,觉得很有用. 一.介绍: 我们要在网页中正常显示flash内容,那么页面中必须要有指定flash路径的标签.也就是OB ...

  9. 在WebStorm里配置watcher实现编辑less文件时自动生成.map和压缩后的.css文件

    [文件(File)]-[设置(Settings)]-[工具(Tools)]-[File Watchers]-[+]-[Less]打开New Watcher配置界面. https://blog.csdn ...

  10. 注解ConfigurationProperties注入yml配置文件中的数据

    在使用SpringBoot开发中需要将一些配置参数放在yml文件中定义,再通过Java类来引入这些配置参数 SpringBoot提供了一些注解来实现这个功能 ConfigurationProperti ...