当前位置: 首页 > 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…...

Qwen3.5-27B镜像合规审计:GDPR/等保2.0/数据出境安全评估要点

Qwen3.5-27B镜像合规审计&#xff1a;GDPR/等保2.0/数据出境安全评估要点 1. 模型与部署概述 Qwen3.5-27B是Qwen官方发布的视觉多模态理解模型&#xff0c;支持文本对话与图片理解功能。本镜像已在4 x RTX 4090 D 24GB环境完成部署&#xff0c;提供中文Web对话界面、流式文本…...

黑丝空姐-造相Z-Turbo构建AI编程助手:自动生成前端组件配图

黑丝空姐-造相Z-Turbo构建AI编程助手&#xff1a;自动生成前端组件配图 想象一下这个场景&#xff1a;你正在为一个航空公司的内部管理系统编写前端代码&#xff0c;需要创建一个“机组人员资料卡”组件。你已经写好了HTML结构和CSS样式&#xff0c;但卡在了头像占位符上——是…...

避开时区陷阱:React Spectrum日期时间处理完全指南

避开时区陷阱&#xff1a;React Spectrum日期时间处理完全指南 【免费下载链接】react-spectrum A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences. 项目地址: https://gitcode.com/GitHub_Trending/re/react-sp…...

背栓干挂石材幕墙方式之我见

背栓干挂石材幕墙方式之我见干挂石材幕墙的方法有多种&#xff0c;目前国内常见的有短槽式、背栓式、背槽式等。下面就几种方式发表点自己的浅见&#xff0c;希望能对大家有帮助。1、短槽式&#xff08;T型件或蝴蝶件&#xff09;&#xff1a;该方式是在石材上下面开槽&#xf…...

震惊!Claude Code 藏着 117 个大招,你竟然只用了 3 个?

每天免费领 1亿 Token&#xff0c;白嫖DeepSeek、GLM、MiniMax、Kimi等大模型&#xff01; 我整个人都傻了&#xff01; 大家伙平时用 Claude Code&#xff0c;是不是感觉它就一“高级聊天框”&#xff1f; 让他写段代码&#xff0c;它写&#xff1b;让他修个 Bug&#xff0c;它…...

OpenClaw故障排查大全:Qwen3.5-9B镜像对接7类报错解决

OpenClaw故障排查大全&#xff1a;Qwen3.5-9B镜像对接7类报错解决 1. 开篇&#xff1a;当OpenClaw遇上Qwen3.5-9B-AWQ镜像 上周我在本地部署Qwen3.5-9B-AWQ镜像对接OpenClaw时&#xff0c;经历了从"模型加载失败"到"图片解析异常"的连环坑。这个支持图像…...

WebGL/Three.js性能优化实战:你的3D模型为什么卡?从理解栅格化与渲染管线开始

WebGL/Three.js性能优化实战&#xff1a;从栅格化原理到渲染管线调优 当你用Three.js加载一个精致的3D模型时&#xff0c;是否遇到过页面突然卡顿、风扇狂转的情况&#xff1f;这背后往往与浏览器如何将矢量图形转换为屏幕像素的过程密切相关。今天我们就从栅格化的底层原理出发…...

WSL2多版本Ubuntu共存与切换实战指南

1. 为什么需要多版本Ubuntu共存&#xff1f; 很多开发者可能都遇到过这样的困境&#xff1a;项目A需要Ubuntu 20.04的环境&#xff0c;而项目B又要求使用Ubuntu 24.04的新特性。传统做法是在不同机器或虚拟机中分别部署&#xff0c;但这既浪费资源又增加管理难度。WSL2的出现完…...

药流和人流哪个恢复快?术后修护行业洞察与实用指南

意外怀孕后&#xff0c;药流和人流的恢复差异及术后修护&#xff0c;是女性关注的核心话题&#xff0c;也是孕产修护领域的重点议题。术后修护作为缩短恢复周期、减少并发症的关键&#xff0c;其科学合理性直接影响女性生殖健康。本文结合行业现状与实用经验&#xff0c;探讨药…...

Go - Zerolog使用入门

特点高性能&#xff1a;零分配设计&#xff0c;极高的写入速度&#xff0c;对 GC 几乎无压力。结构化日志&#xff1a;默认输出 JSON 格式&#xff0c;便于日志系统&#xff08;如 ELK、Loki&#xff09;解析和检索。支持 context&#xff1a;可以在请求链路中传递和追加日志字…...