嵌入式面试八股文(三)·野指针产生原因和解决方法、指针函数和函数指针的区别

目录
1. 野指针产生原因和解决方法
1.1 产生的原因
1.1.1 指针未能初始化
1.1.2 指针指向的内存被释放
1.1.3 指针指向的对象被重复释放
1.2 解决方法
1.2.1 初始化指针
1.2.2 指针空置
1.2.3 避免悬挂指针
2. 指针函数和函数指针的区别
2.1 定义不同
2.2 写法不同
2.3 用法不同
2.3.1 指针函数
2.3.2 函数指针
1. 野指针产生原因和解决方法
在代码编写的过程中,可能会出现指针指向的位置未知,从而出现程序错误,这种指针统一称作野指针。野指针出现的原因最常见的如下几种:
1.1 产生的原因
1.1.1 指针未能初始化
如果一个指针变量被声明但没有被初始化,它会包含一个随机的地址,这个地址很可能不指向有效的内存区域。当你尝试访问这个指针所指向的内存时,就会发生未定义行为或者访问非法内存:
#include <stdio.h>int main()
{int* p; // 未初始化的指针*p = 20;// 这里会导致未定义行为,因为p并没有指向有效的内存return 0;
}
1.1.2 指针指向的内存被释放
当一个指针指向的内存区域被显式释放(使用 free 函数或者类似的机制)或者超出了其作用域(例如局部变量的指针超出了函数的范围),该指针就成为了野指针。尝试使用或者间接访问这样的指针会导致未定义行为。
int *ptr;
{int localVar = 10;ptr = &localVar;
} // localVar 超出作用域,ptr 现在是一个野指针// 尝试访问 *ptr 将导致未定义行为
1.1.3 指针指向的对象被重复释放
如果一个指针指向的内存已经被释放,但指针本身仍然保持指向已释放的内存,这也会导致野指针的问题。再次使用这个指针可能会导致不可预测的行为或程序崩溃。
int *ptr = malloc(sizeof(int));
free(ptr);
// 现在 ptr 是一个野指针,指向已释放的内存区域
1.2 解决方法
1.2.1 初始化指针
确保每一个指针在使用前都被正确地初始化。
1.2.2 指针空置
当指针不再需要时,将其设置为 NULL 或者 nullptr(对于 C++)。
1.2.3 避免悬挂指针
在超出作用域之前,确保指针不再指向该作用域内的局部变量。
int *ptr = NULL; // 初始化为 NULL// 使用前检查指针是否为 NULL
if (ptr != NULL) {// 只有在 ptr 不为 NULL 时才使用它
}
2. 指针函数和函数指针的区别
2.1 定义不同
指针函数本质是一个函数,其返回值为指针。
函数指针本质是一个指针,其指向一个函数。
2.2 写法不同
指针函数的*是属于数据类型的,而函数指针的星号是属于函数名的:
指针函数:int* fun(int x,int y);
函数指针:int (*fun)(int x,int y);
简单点理解就是:函数名带括号的就是函数指针,否则就是指针函数。
2.3 用法不同
2.3.1 指针函数
指针函数是一个返回指针的函数。它本质上是一个函数,其返回类型是指针类型。这意味着该函数返回一个指针,指向指定类型的数据。指针函数的声明形式为:
*类型标识符 函数名(参数表)
举个例子,首先声明一个普通的函数:
int fun(int x,int y);
我们在声明一个函数,如:
int *fun(int x,int y);
这和上面那个函数唯一的区别就是在函数名前面多了一个*号,而这个函数就是一个指针函数。其返回值是一个 int 类型的指针,是一个地址。因此想要得到输出值,需要加上解引用运算符*,例如:
#include<stdio.h>// 定义一个指针函数,返回一个整型指针
int* findMax(int arr[], int size) {if (size == 0) return NULL;int* max = &arr[0];for (int i = 1; i < size; ++i) {if (arr[i] > *max) {max = &arr[i];}}return max;
}int main() {int numbers[] = { 1, 3, 7, 2, 5 };int* maxPtr;maxPtr = findMax(numbers, 5); // 调用指针函数printf("Max: %d\n", *maxPtr); // 输出最大值printf("Max: %p\n", maxPtr);return 0;
}
本函数是一个求数组最大值的函数,若是直接出,则会输出地址,因此需要进行解引用:

普通函数则可进行直接输出:
#include <stdio.h>// 定义一个普通函数,返回整型值(最大值)
int findMax(int arr[], int size) {if (size == 0)return 0; // 如果数组为空,返回一个适当的默认值,这里返回0作为示例int max = arr[0];for (int i = 1; i < size; ++i) {if (arr[i] > max) {max = arr[i];}}return max;
}int main() {int numbers[] = { 1, 3, 7, 2, 5 };int max = findMax(numbers, 5); // 调用普通函数找到最大值printf("Max: %d\n", max); // 输出最大值return 0;
}

2.3.2 函数指针
函数指针是指向函数的指针变量。函数指针存储了函数的地址,可以用来调用该函数。它的声明形式为:
int (*fun)(int x,int y);
函数指针是需要把一个函数的地址赋值给它,有两种写法:
fun = &Function;
fun = Function;
取地址运算符&不是必需的,因为一个函数标识符就表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。
调用函数指针的方式也有两种:
x = (*fun)();
x = fun();
我们进行一个简单的运用:
#include<stdio.h>//函数+
int add(int x, int y)
{return x + y;
}//函数指针
int (*fun)(int x, int y);int main()
{int result;// 将函数指针 fun 分别指向 add 和 sub 函数fun = add;result = fun(10, 5); // 调用 add 函数printf("Result of add: %d\n", result);fun = &add;result = fun(10, 5); // 调用 add 函数printf("Result of add: %d\n", result);fun = add;result = (*fun)(10, 5); // 调用 add 函数printf("Result of add: %d\n", result);fun = &add;result = (*fun)(10, 5); // 调用 add 函数printf("Result of add: %d\n", result);return 0;
}


千题千解·嵌入式工程师八股文详解_时光の尘的博客-CSDN博客

相关文章:
嵌入式面试八股文(三)·野指针产生原因和解决方法、指针函数和函数指针的区别
目录 1. 野指针产生原因和解决方法 1.1 产生的原因 1.1.1 指针未能初始化 1.1.2 指针指向的内存被释放 1.1.3 指针指向的对象被重复释放 1.2 解决方法 1.2.1 初始化指针 1.2.2 指针空置 1.2.3 避免悬挂指针 2. 指针函数和函数指针的区别 2.1 定义不同 2…...
OpenCV 中 CV_8UC1,CV_32FC3,CV_32S等参数的含义
在OpenCV中,创建图像时需要指定图像的类型,这些类型通常通过常量来表示,例如 CV_8UC1、CV_32FC3、CV_32S 等。这些常量定义了图像的数据类型和通道数,具体含义如下: CV_8UC1: CV_8U 表示每个像素由一个8位无…...
v 3 + vite + ts 自适应布局(postcss-pxtorem)
1、 当pc端、移动端H5等项目中,需要根据当前浏览器窗口或屏幕尺寸,来自适应的改变页面内元素尺寸时,就可以借助下述插件和相关配置来实现。 2、适用范围:vue3 vite ts 步骤一:相关依赖下载下载相关依赖 npm inst…...
(MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
文章简介 承接上一篇笔记,该份笔记是笔者深思熟虑后根据实战应用所总结出来的精华内容,该文章内容主要包括配置avc权限的使用场景以及其上下环节所需的准备。 使用场景 1.底层驱动有无配置好相应的串口 2.开启相应的selinux avc 权限 3.在framework层配置相应的 (config…...
Linux安全与高级应用(六)Linux Shell脚本编程的高级应用:条件测试与if语句的妙用
文章目录 Linux Shell脚本编程的高级应用:条件测试与if语句的妙用一、条件测试操作详解1. 字符串比较2. 整数比较3. 文件测试4. 逻辑测试 二、if语句的结构与应用1. 单分支结构2. 双分支结构3. 多分支结构 三、实际应用案例1. 需求描述2. 实现思路3. 代码实现4. 设置…...
升级MacOS(Mojave)后使用git问题
将MacOS升级到Mojave版本后,使用git工具时,出现如下错误提示: guochongxindeMacBook-Pro:study guochongxin$ git status . xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Librar…...
基于PFC和ECN搭建无损RoCE网络的工作流程分析
无损RoCE网络概念 RDMA(Remote Direct Memory Access,远程直接内存访问)是一种为了解决网络传输中服务器端数据处理延迟而产生的技术。RDMA 将用户应用中的数据直接传入服务器的存储区,通过网络将数据从一个系统快速传输到远程系…...
射频功率放大器调测简略
射频功率放大器除了在设计时的难度外,其次就是调测阶段,设计时仿真可以通过不断更改仿真参数来达到理想状态,更关键的是不用提心吊胆的把烧器件,而处于调测阶段则很容易出现烧坏器件的情况,特别是功率大的射频功率放大…...
Linux使用docker搭建Redis 哨兵模式
1. Redis Sentinel 简介 Redis Sentinel 是 Redis 高可用解决方案的一部分。它提供了监控、通知和自动故障转移功能,确保 Redis 集群在主节点发生故障时仍然可以继续工作。以下是 Redis Sentinel 的主要功能和作用:监控: Sentinel 会不断检查…...
springboot给类进行赋初值的四种方式
目录 1. 使用Value和ConfigurationProperties2. 使用PropertySource创建Person.java写一个测试类 3. 使用ImportResourceStudent类创建beans.xml在主类中引入测试 其他心得 1. 使用Value和ConfigurationProperties 这里不加赘述了,前面我也发过,这里就放…...
Day32 | 1049. 最后一块石头的重量 II 494. 目标和 474.一和零
语言 Java 1049. 最后一块石头的重量 II 最后一块石头的重量 II 题目 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 …...
linux 查看一个端口是否被占用
1 linux命令 要在Linux中查看一个端口是否被占用,可以按照以下步骤进行操作: 打开终端(Terminal)。 运行以下命令来列出系统上所有正在监听的端口及其对应的进程: sudo netstat -tuln | grep LISTEN这将显示所有正在…...
【Git】5. 配置 Git
配置.gitignore – 忽略特殊⽂件 在⽇常开发中,我们有些⽂件不想或者不应该提交到远端,⽐如保存了数据库密码的配置⽂件,那怎么让 Git 知道呢? 在 Git ⼯作区的根⽬录下创建⼀个特殊的 .gitignore ⽂件,然后把要忽略的…...
C语言:文件处理
文件处理 一、文件的类型(一)文本文件和二进制文件 (二)程序文件和数据文件数据文件按照二进制储存 二、文件的打开和关闭(一)文件指针(二)文件的打开和关闭1、fopen2、fclose &…...
SpringBoot MybatisPlus selectOne的坑
目录 一、问题 二、问题解决 三、其他方法 一、问题 selectOne在查询多条数据时会报错,查询语句并不会加 limit 1。 One record is expected, but the query result is multiple records。 二、问题解决 在QueryWrapper上添加如下: QueryWrapper&…...
Spring源码-ClassPathXmlApplicationContext的refresh()都做了什么?
AbstractApplicationContext的refresh方法 /*** 用给定的父类创建一个新的ClassPathXmlApplicationContext* Create a new ClassPathXmlApplicationContext with the given parent,* 从给定的XML文件加载定义* loading the definitions from the given XML files.* param confi…...
网站加密和混淆技术简介
我们在爬取网站的时候,会遇到一些需要分析接口或 URL 信息的情况,这时会有各种各样类似加密的情况 1. 某个网站的URL 带有一些看不懂的长串加密字符,要抓取就必须懂的这些参数是怎么构造的,否则我们连完整的 URL 都构造不出来&am…...
Kafka + Kraft 集群搭建教程,附详细配置及自动化安装脚本
本文主要介绍 kafka kraft 搭建过程,主要用途是为了日志采集,所以搭建相对比较简单暴力,不过也可以作为一个参考供大家学习,主打一个能用管跑(调优啊,参数解释啊,原理啊,太枯燥了&a…...
“Apple Intelligence”的“系统提示词”被曝光了
当 苹果的 Apple Intelligence 还未完全开放体验时,其提示词就已经曝光了。 苹果如何指挥 AI 干活,这次被泄露的非常彻底。我们就拿邮件来说,借助 AI,收发及回复邮件变得非常简单,但背后的逻辑是内置提示词在拿捏。 比…...
django学习-数据表操作
一、数据表操作 1. 数据新增 由模型实例化对象调用内置方法实现数据新增,比如单数据新增调用create,查询与新增调用get_or_create,修改与新增调用update_or_create,批量新增调用bulk_create。 1.1 create() # 方法一 # 使用cr…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...
