野指针与'关键字'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. SQLServer多表联查,多表分页查询

    多表联查: select p.*,s.Sheng , i.Shifrom  [dbo].[ProductRecordInfo]   --表名 p left join [ShengInfo] s on ...

  2. Storm入门(十)Twitter Storm: Transactional Topolgoy简介

    作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/736/twitter-stor ...

  3. 12.22 大湾区.NET Meet 大会

    今年的 Connect(); 主题更加聚焦开发者工具生产力.开源,以及无服务器(Serverless)云服务. Visual Studio 2019 AI 智能加持的 IntelliCode.实时代码 ...

  4. 利用requirejs实现vue的模块化开发

    通常vue都是搭配webpack+vue-cli使用的 如果不在nodejs环境下开发web应用呢? 这里提出一个解决方案: 1.加载requirejs,并且指定main函数 <script d ...

  5. 快速构建SPA框架SalutJS--项目工程目录 一

    起因 刚进公司那会儿,接的是一个微信APP应用,SPA是前人搭起来的,用到的技术主要是backbone和zepto.后来那人走了,就卤煮一个人把项目接了下来.项目越是到后面,越发觉了诸多弊端,不停的增 ...

  6. String字符串创建与存储机制

    Java内存可以粗略的区分为堆内存(Heap)和栈内存(Stack),堆中存放的是对象实例,而栈中存放的则是方法调用过程中的局部变量或引用等. 在Java语言中,字符串的生命与初始化有如下两种方式: ...

  7. 一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

    1.引言 HTTPS(全称: Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.本文,就来深入介绍下其 ...

  8. 为什么要重写 hashcode 和 equals 方法?

    引言 以前面试的时候被面试官问到过这样一个问题: 你有没有重写过 hashCode 方法? 心里想着我没事重写哪玩意干啥,能不写就不写.嘴上当然没敢这么说,只能略表遗憾的说抱歉,我没写过. 撇了面试官 ...

  9. 使用 coverlet 查看.NET Core应用的测试覆盖率

    代码覆盖(Code coverage)是软件测试中的一种度量,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率. Visual Studio 2017的企业版可以直接查看测试的代码覆盖率, ...

  10. springboot~注册bean的方法

    spring在启动时会自己把bean(java组件)注册到ioc容器里,实现控制反转,在开发人员使用spring开发应用程序时,你是看不到new关键字的,所有对象都应该从容器里获得,它们的生命周期在放 ...