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

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

目录

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中&#xff0c;创建图像时需要指定图像的类型&#xff0c;这些类型通常通过常量来表示&#xff0c;例如 CV_8UC1、CV_32FC3、CV_32S 等。这些常量定义了图像的数据类型和通道数&#xff0c;具体含义如下&#xff1a; CV_8UC1&#xff1a; CV_8U 表示每个像素由一个8位无…...

v 3 + vite + ts 自适应布局(postcss-pxtorem)

1、 当pc端、移动端H5等项目中&#xff0c;需要根据当前浏览器窗口或屏幕尺寸&#xff0c;来自适应的改变页面内元素尺寸时&#xff0c;就可以借助下述插件和相关配置来实现。 2、适用范围&#xff1a;vue3 vite ts 步骤一&#xff1a;相关依赖下载下载相关依赖 npm inst…...

(MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2

文章简介 承接上一篇笔记,该份笔记是笔者深思熟虑后根据实战应用所总结出来的精华内容,该文章内容主要包括配置avc权限的使用场景以及其上下环节所需的准备。 使用场景 1.底层驱动有无配置好相应的串口 2.开启相应的selinux avc 权限 3.在framework层配置相应的 (config…...

Linux安全与高级应用(六)Linux Shell脚本编程的高级应用:条件测试与if语句的妙用

文章目录 Linux Shell脚本编程的高级应用&#xff1a;条件测试与if语句的妙用一、条件测试操作详解1. 字符串比较2. 整数比较3. 文件测试4. 逻辑测试 二、if语句的结构与应用1. 单分支结构2. 双分支结构3. 多分支结构 三、实际应用案例1. 需求描述2. 实现思路3. 代码实现4. 设置…...

升级MacOS(Mojave)后使用git问题

将MacOS升级到Mojave版本后&#xff0c;使用git工具时&#xff0c;出现如下错误提示&#xff1a; guochongxindeMacBook-Pro:study guochongxin$ git status . xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Librar…...

基于PFC和ECN搭建无损RoCE网络的工作流程分析

无损RoCE网络概念 RDMA&#xff08;Remote Direct Memory Access&#xff0c;远程直接内存访问&#xff09;是一种为了解决网络传输中服务器端数据处理延迟而产生的技术。RDMA 将用户应用中的数据直接传入服务器的存储区&#xff0c;通过网络将数据从一个系统快速传输到远程系…...

射频功率放大器调测简略

射频功率放大器除了在设计时的难度外&#xff0c;其次就是调测阶段&#xff0c;设计时仿真可以通过不断更改仿真参数来达到理想状态&#xff0c;更关键的是不用提心吊胆的把烧器件&#xff0c;而处于调测阶段则很容易出现烧坏器件的情况&#xff0c;特别是功率大的射频功率放大…...

Linux使用docker搭建Redis 哨兵模式

1. Redis Sentinel 简介 Redis Sentinel 是 Redis 高可用解决方案的一部分。它提供了监控、通知和自动故障转移功能&#xff0c;确保 Redis 集群在主节点发生故障时仍然可以继续工作。以下是 Redis Sentinel 的主要功能和作用&#xff1a;监控&#xff1a; Sentinel 会不断检查…...

springboot给类进行赋初值的四种方式

目录 1. 使用Value和ConfigurationProperties2. 使用PropertySource创建Person.java写一个测试类 3. 使用ImportResourceStudent类创建beans.xml在主类中引入测试 其他心得 1. 使用Value和ConfigurationProperties 这里不加赘述了&#xff0c;前面我也发过&#xff0c;这里就放…...

Day32 | 1049. 最后一块石头的重量 II 494. 目标和 474.一和零

语言 Java 1049. 最后一块石头的重量 II 最后一块石头的重量 II 题目 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 …...

linux 查看一个端口是否被占用

1 linux命令 要在Linux中查看一个端口是否被占用&#xff0c;可以按照以下步骤进行操作&#xff1a; 打开终端&#xff08;Terminal&#xff09;。 运行以下命令来列出系统上所有正在监听的端口及其对应的进程&#xff1a; sudo netstat -tuln | grep LISTEN这将显示所有正在…...

【Git】5. 配置 Git

配置.gitignore – 忽略特殊⽂件 在⽇常开发中&#xff0c;我们有些⽂件不想或者不应该提交到远端&#xff0c;⽐如保存了数据库密码的配置⽂件&#xff0c;那怎么让 Git 知道呢&#xff1f; 在 Git ⼯作区的根⽬录下创建⼀个特殊的 .gitignore ⽂件&#xff0c;然后把要忽略的…...

C语言:文件处理

文件处理 一、文件的类型&#xff08;一&#xff09;文本文件和二进制文件 &#xff08;二&#xff09;程序文件和数据文件数据文件按照二进制储存 二、文件的打开和关闭&#xff08;一&#xff09;文件指针&#xff08;二&#xff09;文件的打开和关闭1、fopen2、fclose &…...

SpringBoot MybatisPlus selectOne的坑

目录 一、问题 二、问题解决 三、其他方法 一、问题 selectOne在查询多条数据时会报错&#xff0c;查询语句并不会加 limit 1。 One record is expected, but the query result is multiple records。 二、问题解决 在QueryWrapper上添加如下&#xff1a; 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…...

网站加密和混淆技术简介

我们在爬取网站的时候&#xff0c;会遇到一些需要分析接口或 URL 信息的情况&#xff0c;这时会有各种各样类似加密的情况 1. 某个网站的URL 带有一些看不懂的长串加密字符&#xff0c;要抓取就必须懂的这些参数是怎么构造的&#xff0c;否则我们连完整的 URL 都构造不出来&am…...

Kafka + Kraft 集群搭建教程,附详细配置及自动化安装脚本

本文主要介绍 kafka kraft 搭建过程&#xff0c;主要用途是为了日志采集&#xff0c;所以搭建相对比较简单暴力&#xff0c;不过也可以作为一个参考供大家学习&#xff0c;主打一个能用管跑&#xff08;调优啊&#xff0c;参数解释啊&#xff0c;原理啊&#xff0c;太枯燥了&a…...

“Apple Intelligence”的“系统提示词”被曝光了

当 苹果的 Apple Intelligence 还未完全开放体验时&#xff0c;其提示词就已经曝光了。 苹果如何指挥 AI 干活&#xff0c;这次被泄露的非常彻底。我们就拿邮件来说&#xff0c;借助 AI&#xff0c;收发及回复邮件变得非常简单&#xff0c;但背后的逻辑是内置提示词在拿捏。 比…...

django学习-数据表操作

一、数据表操作 1. 数据新增 由模型实例化对象调用内置方法实现数据新增&#xff0c;比如单数据新增调用create&#xff0c;查询与新增调用get_or_create&#xff0c;修改与新增调用update_or_create&#xff0c;批量新增调用bulk_create。 1.1 create() # 方法一 # 使用cr…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...