野指针与'关键字'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. 有关Windows10中诊断和反馈隐私设置

    当你使用 Windows 时,我们将收集诊断信息,为了确保能收到你(我们的客户)的反馈,我们为你提供了多种方式,以便你可以随时发送反馈,也可以在某个特定的时间(例如当 Windows 10 向你提出关 ...

  2. widows10 安装1803 版本后不能访问网络上的机器解决方法

    安装Windows10 1803 版本后,发现网络上的机器好多不见了. 使用 ping  可以ping 通,但是访问网络共享提示下面错误. 这个原因是1803 中没有安装 SMB1.0 协议.因为 S ...

  3. ASP.NET Core 快速入门(环境篇)

    [申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是让你精通Linux ... 的开机与关机.nginx安装与部署.Core的Hello World .. ...

  4. vue2.0 日历日程表 ,可进行二次开发.

    由于工作业务需求,要写一个日程表,日程表写之前 要先生成日历,废话不多说,直接 上代码: <!DOCTYPE html> <html lang="zh-CN"&g ...

  5. 【RL-TCPnet网络教程】第40章 RL-TCPnet之TFTP客户端(精简版)

    第40章      RL-TCPnet之TFTP客户端 本章节为大家讲解RL-TCPnet的TFTP客户端应用,学习本章节前,务必要优先学习第38章的TFTP基础知识.有了这些基础知识之后,再搞本章节 ...

  6. ajax data属性传值的方式总结

    在和后台同事对接口的时候,有一个小问题一直困扰着我.那就是用ajax请求后台接口数据,需要用data属性传值的时候,data属性传值的方式感觉没有统一用一种方式. 后来仔细想想,其实哪种方式都可以,主 ...

  7. javascript权威指南笔记[6-8]

    1.三类对象,两类属性 2.原型链只有在查询的时候才会体现 3.对象属性访问 4.属性赋值 5.delete只是断开属性和宿主对象的关系,不会去操作属性中的属性 6.Object.ke() var m ...

  8. 把ABP框架部署到Docker中

    本文旨在将Abp项目部署到Docker容器中,借助Gitee存储,Jenkins持续构建,利用Docker Compose生成镜像.启动镜像,在官网给定的Abp项目中,虽然用到了Dockerfile. ...

  9. 【Python3爬虫】百度一下,坑死你?

    一.写在前面 这个标题是借用的路人甲大佬的一篇文章的标题(百度一下,坑死你),而且这次的爬虫也是看了这篇文章后才写出来的,感兴趣的可以先看下这篇文章. 前段时间有篇文章<搜索引擎百度已死> ...

  10. Python命令行参数解析模块argparse

    当写一个Python脚本时经常会遇到不同参数不同功能的情况,如何做一个更好看的命令帮助信息以及对命令参数解析呢? 这就需要使用argparse模块 #!/usr/bin/env python # -* ...