当前位置: 首页 > news >正文

详解C语言中的野指针和assert断言

目录

  • 1.野指针
    • 1.1 野指针成因
      • 1.1.1 指针未初始化
      • 1.1.2 指针越界访问
      • 1.1.3 指针指向的空间释放
    • 1.2 如何规避野指针
      • 1.2.1 指针初始化
      • 1.2.2 小心指针越界
      • 1.2.3 指针变量不再使用时,及时置为NULL,指针使用之前检查
      • 1.2.4 避免返回局部变量的地址
  • 2.assert断言

1.野指针

概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)。

1.1 野指针成因

1.1.1 指针未初始化

对比下面2段代码:

//代码1
#include <stdio.h>int main()
{int a = 10;int* p = &a;*p = 20;return 0;
}
//代码2
#include <stdio.h>int main()
{int* p ;*p = 20;return 0;
}

代码1中指针变量p明确指向了a,进行了初始化。

代码2中指针变量p未进行初始化,p是一个局部变量,一个局部变量不初始化,默认是随机值。此时p就是一个野指针!!

1.1.2 指针越界访问

上代码:

#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr; //p此时不是野指针int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i <= sz; i++){printf("%d ", *p);p++;}return 0;
}

画图演示为:
在这里插入图片描述
当p访问至下标为10的时候,越界访问,此时p就是野指针!!

1.1.3 指针指向的空间释放

上代码:

#include <stdio.h>int* test()
{int a = 10;return &a;
}int main()
{int* p = test();printf("%d\n", *p);return 0;
}

画图演示如下:
在这里插入图片描述

按道理来说,p可以通过存放的a的地址来找到a,遗憾的是离开test函数时,a的空间已经还给操作系统了,已经不属于a了,但是a的地址又给p了,当我们对p中的地址进行解引用时,此时p中的地址就是野指针了!!

1.2 如何规避野指针

1.2.1 指针初始化

  1. 明确知道指针应该指向哪里,就初始化一个明确的地址。
  2. 如果现在还不知道该指向哪里,就初始化NULL

注:NULL是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的,读写该地址会报错

例如:

#include <stdio.h>int main()
{int a = 10;int* p1 = &a;//初始化一个明确地址int* p2 = NULL;//初始化为NULLreturn 0;
}

1.2.2 小心指针越界

⼀个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是越界访问。

1.2.3 指针变量不再使用时,及时置为NULL,指针使用之前检查

当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使⽤这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的⼀个规则就是:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL。

我们可以把野指针想象成野狗,野狗放任不管是⾮常危险的,所以我们可以找⼀棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。

不过野狗即使拴起来我们也要绕着走,不能去挑逗野狗,有点危险;对于指针也是,在使用之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直使⽤,如果不是我们再去使用

1.2.4 避免返回局部变量的地址

如造成野指针的第三个例子,不要返回局部变量的地址。

2.assert断言

assert.h头文件定义了宏assert(),用于在运行时确保程序符合指定条件,如果不符合,就报错终止。这个宏常常被称为“断言

assert ( p ! = NULL );

assert()宏接收一个表达式作为参数,如果该表达式为真(返回值非零),assert()不会产生任何作用,程序继续运行。如果表达式为假(返回值为0),assert()就会报错,在stderr 中写入一条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。

例如:
在这里插入图片描述

相关文章:

详解C语言中的野指针和assert断言

目录 1.野指针1.1 野指针成因1.1.1 指针未初始化1.1.2 指针越界访问1.1.3 指针指向的空间释放 1.2 如何规避野指针1.2.1 指针初始化1.2.2 小心指针越界1.2.3 指针变量不再使用时&#xff0c;及时置为NULL&#xff0c;指针使用之前检查1.2.4 避免返回局部变量的地址 2.assert断言…...

Vue源码系列讲解——模板编译篇【四】(文本解析器)

1. 前言 在上篇文章中我们说了&#xff0c;当HTML解析器解析到文本内容时会调用4个钩子函数中的chars函数来创建文本型的AST节点&#xff0c;并且也说了在chars函数中会根据文本内容是否包含变量再细分为创建含有变量的AST节点和不包含变量的AST节点&#xff0c;如下&#xff…...

微信小程序开发学习笔记《17》uni-app框架-tabBar

微信小程序开发学习笔记《17》uni-app框架-tabBar 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、创建tabBar分支 运行如下的命令&#xff0c;基于master分支在本地创建tabBar子分支&#x…...

《区块链公链数据分析简易速速上手小册》第5章:高级数据分析技术(2024 最新版)

文章目录 5.1 跨链交易分析5.1.1 基础知识5.1.2 重点案例&#xff1a;分析以太坊到 BSC 的跨链交易理论步骤和工具准备Python 代码示例构思步骤1: 设置环境和获取合约信息步骤2: 分析以太坊上的锁定交易步骤3: 跟踪BSC上的铸币交易 结论 5.1.3 拓展案例 1&#xff1a;使用 Pyth…...

【芯片设计- RTL 数字逻辑设计入门 15 -- 函数实现数据大小端转换】

文章目录 函数实现数据大小端转换函数语法函数使用的规则Verilog and Testbench综合图VCS 仿真波形 函数实现数据大小端转换 在数字芯片设计中&#xff0c;经常把实现特定功能的模块编写成函数&#xff0c;在需要的时候再在主模块中调用&#xff0c;以提高代码的复用性和提高设…...

Codeforces Round 925 (Div. 3) D. Divisible Pairs (Java)

Codeforces Round 925 (Div. 3) D. Divisible Pairs (Java) 比赛链接&#xff1a;Codeforces Round 925 (Div. 3) D题传送门&#xff1a;D.Divisible Pairs 题目&#xff1a;D.Divisible Pairs 题目描述 输出格式 For each test case, output a single integer — the num…...

【C语言】实现单链表

目录 &#xff08;一&#xff09;头文件 &#xff08;二&#xff09;功能实现 &#xff08;1&#xff09;打印单链表 &#xff08;2&#xff09;头插与头删 &#xff08;3&#xff09;尾插与尾删 &#xff08;4&#xff09; 删除指定位置节点 和 删除指定位置之后的节点 …...

Hive调优——合并小文件

目录 一、小文件产生的原因 二、小文件的危害 三、小文件的解决方案 3.1 小文件的预防 3.1.1 减少Map数量 3.1.2 减少Reduce的数量 3.2 已存在的小文件合并 3.2.1 方式一&#xff1a;insert overwrite (推荐) 3.2.2 方式二&#xff1a;concatenate 3.2.3 方式三&#xff…...

设计模式(行为型模式)责任链模式

目录 一、简介二、责任链模式2.1、处理器接口2.2、具体处理器类2.3、使用 三、优点与缺点 一、简介 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;允许你将请求沿着处理者链进行传递&#xff0c;直到有一个处理者能够处理…...

HTTP和HTTPS区别!

http 是我们几乎天天都要打交道的东西&#xff0c;相关知识点有点多&#xff0c;所以也有不少面试必问的点&#xff0c;这里做了一些整理&#xff0c;帮且大家树立完整的 http 知识体系&#xff0c;对面试官说 so easy HTTP 的特点和缺点 特点&#xff1a;无连接、无状态、灵…...

麻将普通胡牌算法(带混)

最近在玩腾讯的麻将游戏,但是经常需要充值,于是就想自己实现一个简单的单机麻将游戏.第一个难点就是实现胡牌的判断.这里写一下心得. 术语 本文的胡牌是指手牌构成了3N2的牌型,即一对做将,剩下的牌均为刻子(3张一样的牌)或者顺子(3张连续的牌比如234饼). 下面就是一个14张牌…...

Rust结构体详解:定义、使用及方法

Rust 是一门强调安全性和性能的系统级编程语言&#xff0c;它引入了结构体&#xff08;struct&#xff09;作为一种自定义的数据类型&#xff0c;允许程序员以更加灵活的方式组织和操作数据。在本篇博客中&#xff0c;我们将深入探讨 Rust 结构体的定义、使用以及相关概念。 什…...

LeetCode、435. 无重叠区间【中等,贪心 区间问题】

文章目录 前言LeetCode、435. 无重叠区间【中等&#xff0c;贪心 区间问题】题目链接及分类思路贪心、区间问题 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技…...

【实战】一、Jest 前端自动化测试框架基础入门(三) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(三)

文章目录 一、Jest 前端自动化测试框架基础入门7.异步代码的测试方法8.Jest 中的钩子函数9.钩子函数的作用域 学习内容来源&#xff1a;Jest入门到TDD/BDD双实战_前端要学的测试课 相对原教程&#xff0c;我在学习开始时&#xff08;2023.08&#xff09;采用的是当前最新版本&a…...

信息学奥赛一本通1228:书架

1228&#xff1a;书架 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 18190 通过数: 10557 【题目描述】 John最近买了一个书架用来存放奶牛养殖书籍&#xff0c;但书架很快被存满了&#xff0c;只剩最顶层有空余。 John共有N&#xfffd;头奶牛(1≤N≤20,0001≤…...

红队打靶练习:GLASGOW SMILE: 1.1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、gobuster 2、dirsearch WEB web信息收集 /how_to.txt /joomla CMS利用 1、爆破后台 2、登录 3、反弹shell 提权 系统信息收集 rob用户登录 abner用户 penguin用户 get root flag 信息收集…...

网络安全的今年:量子、生成人工智能以及 LLM 和密码

尽管世界总是难以预测&#xff0c;但网络安全的几个强劲趋势表明未来几个月的发展充满希望和令人担忧。有一点是肯定的&#xff1a;2024 年将是非常重要且有趣的一年。 近年来&#xff0c;人工智能&#xff08;AI&#xff09;以令人难以置信的速度发展&#xff0c;其在网络安全…...

【FPGA】Verilog:奇偶校验位发生器 | 奇偶校验位校验器

目录 0x00 奇偶校验位发生器 0x01 奇偶校验位校验器 0x02 错误检测器和纠错器...

【心得】关于STM32中RTC的校准方法

最近看了一些关于RTC校准的帖子&#xff0c;发现很多人存在疑惑。正好最近我也在STM32中实现了RTC校准。发些心得。这些对老手来说有些罗索&#xff0c;但对新手有益处。 实现RTC 校准的核心之一是库文件Stm321f0x_bkp.c中的void BKP_SetRTCCalibrationValue (uint8_t Calibra…...

消息中间件面试篇

目录 消息中间件 RabbitMQ 消息不丢失 生产者确认机制 消息持久化 交换机持久化 队列持久化 消息持久化 消费者确认 消息重复消费 出现的场景 解决方案 每条消息设置一个唯一的标识id 幂等方案&#xff1a;【 分布式锁、数据库锁&#xff08;悲观锁、乐观锁&#…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...