C经典BUG:给void*传递char **是不会报错的,连警告都没有

初级代码游戏的专栏介绍与文章目录-CSDN博客

        我们知道C语言的void*表示无类型的指针,或者说,void*可以接受任何指针,这简直就是个魔法。

        这个魔法意味着你可以做任何事,也意味着BUG。

        我今天花了一些时间来解决一个BUG。本来一切都很顺利,我早已经完成了验证代码,测试通过,我只需要把测试代码移植一下,添加一点包装就可以了。

        代码主要用到了read和write函数(这太基本了啊),然而却发现读写数据不正确,但是读写的字节数是正确的,输出读写内容也是正确的,传到对方却全错了。

        测试代码大致是这样的:

    char ch;int i = 0;while (++i<10){ret = read(fd, &ch, 1);//注意这里是&chif (ret < 1){printf("read fail, ret is %d\r\n", ret);}else{printf("recv a char:[0x%02x][%c]\r\n", ch, ch);ret = write(fd, &ch, 1);//注意这里是&chprintf("write [%c] , ret is %d!\r\n", ch, ret);}}

        这就是个串口回吐程序,读一个字节吐回一个字节,重点是串口初始化部分,跟现在说的问题无关,没有贴出来。

        修改后的程序当然不能这么简单,所以就改造了一下:

	bool Send(char const* data, int len){。。。。。int n = write(fd, &data, len);//注意这里是&dataif (n < 0){thelog << "串口写入失败 " << errno << " : " << strerror(errno) << ende;return false;}。。。。。。}bool Recv(char* buf, int len, long* recvLen, int timeout_ms){*recvLen = 0;。。。。。int n = read(fd, &buf + *recvLen, len - *recvLen);//注意这里是&bufif (n > 0){*recvLen += n;}。。。。。。}

        然后传输的数据就是一堆乱码啊……跟踪了半天终于想起来,会不会是指针错了啊?

        仔细一看果然,原来read/write的参数来自char,所以参数是&ch,新改的代码参数换成了char *,我还是保留了&啊,这就变成了char **,而这两个参数要求的是void*,所以完全合法啊,编译器当然不会有任何表示,但是世纪传入的值却错了。

        为什么要允许用void*做参数类型啊?

(这里是结束)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/742460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

王道OnlineJudge 14

题目 二叉树层次建树就是一层一层的建树&#xff0c;从左到右。随着纵向层次的深入&#xff0c;结点的数量变化规律为&#xff1a;1→2→4→8→16→32。 先画图&#xff0c;然后看图可闭眼写代码 右边为辅助队列&#xff0c;有多少个二叉树结点&#xff0c;就有多少个辅助队…

【JavaScript】数据类型转换 ① ( 隐式转换 和 显式转换 | 常用的 数据类型转换 | 转为 字符串类型 方法 )

文章目录 一、 JavaScript 数据类型转换1、数据类型转换2、隐式转换 和 显式转换3、常用的 数据类型转换4、转为 字符串类型 方法 一、 JavaScript 数据类型转换 1、数据类型转换 在 网页端 使用 HTML 表单 和 浏览器输入框 prompt 函数 , 接收的数据 是 字符串类型 变量 , 该…

第6章:MATLAB文本数据处理进阶篇的目录 (MATLAB入门课程)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 第6章&#xff1a;MATLAB文本数据处理进阶篇 6.1 文本格式化 …

爆肝整理万能sass框架:react18+webpack5+typescript+ant Design,框架在手,交付无忧!!!

来活了&#xff0c;要求一周时间内快速给xxx业务开发一个sass系统平台&#xff0c;要求有角色权限控制&#xff0c;推荐模块&#xff0c;各种业务内容模块&#xff0c;莫慌&#xff0c;直接上代码&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 1.系统框架配置…

DAY by DAY 史上最全的Linux常用命令汇总----命令格式

命令行基本操作 命令使用方法 Linux命令格式&#xff1a; command [-options] [parameter1] … 1 command: 命令名&#xff1b; [-options]&#xff1a;选项,可用来对命令进行控制&#xff0c;也可以省略&#xff0c;[]代表可选 parameter1 …&#xff1a;传给命令的参数&a…

带你摸透C语言相关内存函数

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

Windows10/11配置WSL(Ubuntu)环境

文章目录 WSL介绍WSL部署扩展&#xff1a;辅助工具Windosw Terminal安装下载 WSL介绍 传统方式获取Linux操作系统&#xff0c;是安装完整的虚拟机及镜像环境&#xff0c;例如虚拟机VMware 而使用WSL,可以以非常轻量化的方式&#xff0c;得到Linux系统环境 它无需单独虚拟一套硬…

【Linux】常用基础命令(一)

命令的提示符 [rootlocalhost: ~]# []&#xff1a;这是提示符的分隔符号&#xff0c;没有特殊含义。root&#xff1a;显示的是当前的登录用户&#xff1a;分隔符&#xff0c;没有特殊含义。localhost&#xff1a;当前系统的简写主机名&#xff08;完整主机名是 localhost.loc…

校园兼职无忧网-创业计划书(附下载)

校园兼职无忧网是一个致力于为在校大学生提供兼职工作机会的平台&#xff0c;旨在搭建一个便捷、高效、安全的信息对接服务。该平台通过整合校内外各类兼职资源&#xff0c;包括但不限于家教、促销、实习等岗位&#xff0c;帮助学生找到适合自己的兼职工作&#xff0c;同时为用…

PostGIS 中的 K-Means 聚类操作及应用

K-Means算法&#xff1a; K-means 是数据科学和商业的基本算法。让我们深入了解一下。 1. K-means是一种流行的用于聚类的无监督机器学习算法。它是用于客户细分、库存分类、市场细分甚至异常检测的核心算法。 2. 无监督&#xff1a;K-means 是一种无监督算法&#xff0c;用于…

【Git】git pull fatal: refusing to merge unrelated histories

本地项目add到远程仓库后 git remote add origin https://gitee.com/xxx/git-test.git[仓库地址]通过 git pull 拉取远程仓库 显示 fatal: refusing to merge unrelated histories git fetch 没问题git merge 显示&#xff1a;fatal: refusing to merge unrelated histories …

leetcode刷题(javaScript)——分治思想(二分查找、快速排序)相关场景题总结

分治思想是一种将问题分解成更小的子问题&#xff0c;然后解决子问题并将结果合并的算法设计策略。二分查找、快速排序和折半查找都属于分治思想的经典算法。在leetcode里&#xff0c;分治思想一般结合其他场景出现&#xff0c;构成复合型题目。但是在看题时一定要了解能否用分…

C语言分析基础排序算法——计数排序

目录 计数排序 计数排序基本思路 计数排序改进思路 计数排序 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。具体思路为&#xff1a; 统计相同元素出现次数根据统计的结果将序列回收到原来的序列中 计数排序基本思路 基本思路分析&#xff1a; //以…

Qt的定时器QTimer

定时器Qtimer&#xff1a;用于重复执行或延迟执行函数的类。它可以在一定的时间间隔内发出信号。 使用它&#xff0c;只需要创建一个QTimer类对象&#xff0c;然后调用start()函数开启定时器即可。 定时器的信号 当定时器超时后&#xff0c;就会发出一个timeout的信号函数。 …

安卓项目:app注册/登录界面设计

目录 第一步&#xff1a;设计视图xml 第二步&#xff1a;编写登录和注册逻辑代码 运行效果展示&#xff1a; 总结&#xff1a; 提前展示项目结构&#xff1a; 第一步&#xff1a;设计视图xml 在layout目录下面创建activity_login.xml和activity_main.xml文件 activity_lo…

数据库(一):基本语法一

数据库第二次作业 姓名&#xff1a;~~~&#xff0c;学号&#xff1a;~~~&#xff0c;专业&#xff1a;~~~ 2.66 书写SQL查询来获取以下结果: A.星期五的 ChangeClose。 SELECT ChangeClose FROM NDX WHERE TDayOfWeek Friday;B.星期五的最小、最大和平均 ChangeClose。 …

19.创建帖子

文章目录 一、建立路由二、开发CreatePostHandler三、编写logic四、编写dao层五、编译测试运行 一、建立路由 这里要稍微注意的是&#xff1a;需要登录后才可以发表帖子&#xff0c;所以需要用到我们之前写的鉴权中间件。中间件对用户携带的token解析成功后&#xff0c;便会将…

String、StringBuilder、StringBuffer 有什么区别?

1、典型回答 String、StringBuilder 和 StringBuffer 都是 Java 语言中&#xff0c;用于操作字符串的类&#xff0c;但它们在性能、可变性和线程安全性方面有一些区别 1、String&#xff1a;不可变字符串类&#xff0c;也就是说一旦创建&#xff0c;它的值就不可变。每次对 S…

Spring boot 集成netty实现websocket通信

一、netty介绍 Netty 是一个基于NIO的客户、服务器端的编程框架&#xff0c;使用Netty 可以确保你快速和简单的开发出一个网络应用&#xff0c;例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程&#xff0c;例如&#xff1a;基于TCP和U…

Loader、source

Loader 是在 QML 中用于动态加载和创建其他 QML 文件或组件的元素。它允许您根据需要在运行时加载和实例化其他的 QML 文件&#xff0c;以实现动态性和灵活性。 以下是一个简单的示例&#xff0c;展示了如何在 QML 中使用 Loader&#xff1a; Loader {sourceComponent: MyCom…