一个疏忽引发的思考!(strerror)

  前几天写代码因为自己的疏忽导致一遍又一遍的Segmentation fault (core dumped)。该问题是因为strerror(errno)返回的指针指向非法的内存导致程序打印错误时崩溃。

  尝试数次无果,为了进度。简单粗暴的换成了perror(str)。今天忙里偷闲,定位到了问题做个记录和分享。

  所有的坑,都是自己挖的。开始正题。

  

  1 #include<stdio.h>2 #include<errno.h>3 //#include<string.h>4 int main()5 {6     char *perr = NULL;7     errno = 14;8     perr = strerror(errno);9     puts(perr);10     return 0;11 } 

  先看代码,上述我屏蔽了#include<string.h>。如我所料,编译通过(其实有warn已经告诉你有问题了),运行崩溃了。warn如下:

  

  然后加上#include<string.h>程序完美编译,完美成功执行。为什么呢?经过与人(CSDN某某某)讨论和浏览stackoverflow上的帖子,以及我最终使用gcc -E预编译  gcc -Wall的验证。

  

  我得到以下结论。

  1.strerror()函数声明在string.h头文件里(我以前以为是在errno.h里的,还是基本功不行啊)。

  2.gcc编译时如果发现未定义的函数,它会认为该函数是定义在其他源文件中的,所以编译是通过的。

  但是因为编译器看不见函数原型,所以它认为函数返回值为int。在链接阶段,如果找到该函数则通过,找不到则报错。
    这里我做了个实验,如果函数原型在.o文件里链接后没有问题,连接器会修正返回值类型。但是如果链接的是.so文件,则返回值就是int。我也想不明白。

  

  揭晓答案吧!我的程序为什么会报错呢?这是一系列疏忽大意加基本功不扎实的恶果。

  因为我没有包string.h。所以编译器看不见函数原型,默认函数返回值为int。并给出了wara:assignment makes pointer from integer without a cast(用一个int型给指针赋值而没有转换--英文不好)。显而易见,在64位系统中char*是64位的,int是32位。所以相当于我用32位的整型值当作地址赋值给了指针。所以指针指向非法内存。接着Segmentation fault (core dumped)就登场了。

  系统中类型于strerror()这种返回指针的函数都可能有类似问题,所以头文件该包的还是要包上。该注意的warn还是不容忽视啊。

  文章到此已经结束,给个附录。64位系统 gcc编译器 各个数据类型长度表。

  

  
  以上阐述由非权威人士撰写。如有大牛深谙其理,欢迎跟帖深入说明。

转载于:https://www.cnblogs.com/acool/p/4708483.html

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

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

相关文章

Java最佳实践–字符串性能和精确字符串匹配

在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将讨论String性能调优。 我们将专注于如何有效地处理字符串创建&#xff0c; 字符串更改和字符串匹配操作。 此外&#xff0c;我们将提供我们自己的用于精确字符串匹配的最常用算法的…

keil里面填数据

编译后寄存器和堆栈的内存数据可以直接写进去的。 寄存器&#xff0c;双击就可以&#xff0c;注意里面是十六进制 堆栈&#xff0c;也是十六进制&#xff0c;八位的 00 00 00 00 &#xff0c;但这个是从右到左的&#xff0c;比如0x00000006 应该填 06 00 00 00 把数据取出来 取…

调试生产服务器– Eclipse和JBoss展示

您是否编写有错误的代码&#xff1f; 不&#xff0c;当然不。 对于我们其余的确实会编写带有错误的代码的凡人&#xff0c;我想解决一个非常敏感的问题&#xff1a;调试在生产服务器上运行的应用程序。 因此&#xff0c;您的应用程序已准备好进行部署。 单元测试全部成功&…

力扣151. 翻转字符串里的单词

给你一个字符串 s &#xff0c;逐个翻转字符串中的所有 单词 。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。 没思路&#xff0c;看到的官方给的&#xff0c;简洁明了&…

B/S和C/S架构图解

软件&#xff1a;B/S和C/S两种架构模式。接下来用三张图片解释&#xff0c;什么是B/S什么是C/S。 图片一&#xff1a;软件架构模式 图片二&#xff1a;C/S结构模式 图片三&#xff1a;B/S结构模式 相信图解胜过冗长文字的解释&#xff0c;什么是B/S什么是C/S一目了然。 转载于:…

HDU 5371 Hotaru's problem (Manacher,回文串)

题意&#xff1a;给一个序列&#xff0c;找出1个连续子序列&#xff0c;将其平分成前&#xff0c;中&#xff0c;后等长的3段子序列&#xff0c;要求【前】和【中】是回文&#xff0c;【中】和【后】是回文。求3段最长为多少&#xff1f;由于平分的关系&#xff0c;所以答案应该…

bash 与 dash

Ubuntu 的 bash和dash的区别 什么是bash &#xff1f; Bash(GNU Bourne-Again Shell)是许多Linux平台的内定Shell&#xff0c;事实上&#xff0c;还有许多传统UNIX上用的Shell&#xff0c;像tcsh、csh、ash、bsh、ksh等 等&#xff0c;Shell Script大致都类同&#xff0c;当您学…

Eclipse:如何附加Java源代码

在Eclipse中&#xff0c;当您按Ctrl按钮并单击任何类名称时&#xff0c;IDE会将您带到该类的源文件。 这是项目中具有的类的正常行为。 但是&#xff0c;如果您也希望Java核心类具有相同的行为&#xff0c;则可以通过将Java源代码附加到Eclipse IDE来实现。 一旦附加了源代码&a…

h.264 去块滤波

块效应及其产生原因 我们在观看视频的时候&#xff0c;在运动剧烈的场景常能观察到图像出现小方块&#xff0c;小方块在边界处呈现不连续的效果&#xff08;如下图&#xff09;&#xff0c;这种现象被称为块效应&#xff08;blocking artifact&#xff09;。 首先我们需要搞清楚…

DataNucleus 3.0与Hibernate 3.5

如官方产品站点所述&#xff0c; DataNucleus Access Platform是现有的最符合标准的开源Java持久性产品。 它完全符合JDO1 &#xff0c; JDO2 &#xff0c; JDO2.1 &#xff0c; JDO2.2 &#xff0c; JDO3 &#xff0c; JPA1和JPA2 Java标准。 它还符合OGC简单功能规范&#xf…

AngularJS 的常用特性(二)

3、列表、表格以及其他迭代型元素 ng-repeat可能是最有用的 Angular 指令了&#xff0c;它可以根据集合中的项目一次创建一组元素的多份拷贝。 比如一个学生名册系统需要从服务器上获取学生信息&#xff0c;目前先把模型之间定义在 JavaScript 代码里面&#xff1a; 1 var stud…

Ruby,Python和Java中的Web服务

今天&#xff0c;我不得不准备一些示例来说明Web服务是可互操作的。 因此&#xff0c;我已经使用Metro使用Java创建了一个简单的Web服务&#xff0c;并在Tomcat上启动了它。 然后尝试使用Python和Ruby消耗它们。 这是全部完成的过程… Java中的Web服务 我从Java中的简单Web服…

用动画切换按钮的状态

用动画切换按钮的状态 效果 源码 https://github.com/YouXianMing/UI-Component-Collection // // BaseControl.h // BaseButton // // Created by YouXianMing on 15/8/27. // Copyright (c) 2015年 YouXianMing. All rights reserved. //#import <UIKit/UIKit.h> c…

Java泛型快速教程

泛型是Java SE 5.0引入的一种Java功能&#xff0c;在其发布几年后&#xff0c;我发誓那里的每个Java程序员不仅听说过它&#xff0c;而且已经使用过它。 关于Java泛型&#xff0c;有很多免费和商业资源&#xff0c;而我使用的最佳资源是&#xff1a; Java教程 Java泛型和集合…

876. 链表的中间结点

给定一个头结点为 head 的非空单链表&#xff0c;返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点 代码一&#xff1a; 自己想的一个方法 class Solution {public ListNode middleNode(ListNode head) {ListNode p1 head;ListNode p2 head;//i,j…

Spark系列—02 Spark程序牛刀小试

一、执行第一个Spark程序 1、执行程序 我们执行一下Spark自带的一个例子&#xff0c;利用蒙特卡罗算法求PI&#xff1a; 启动Spark集群后&#xff0c;可以在集群的任何一台机器上执行一下命令&#xff1a; /home/spark/spark-1.6.1-bin-hadoop2.6/bin/spark-submit \ --class o…

JVM选项:-client vs -server

您是否曾经在运行Java应用程序时想知道-client或-server开关是什么&#xff1f; 例如&#xff1a; javaw.exe -client com.blogspot.sdoulger.LoopTest也显示在java.exe的“帮助”中&#xff0c;例如&#xff0c;其中的选项包括&#xff1a; -client选择“客户端” VM -serv…

3.1存储管理操作系统

存储器管理的对象是主存&#xff08;内存&#xff09;。其主要功能包含分配和回收主存空间、提高主存的利用率、扩充主存、对主存信息实现有效保护。存储器的结构为&#xff1a;寄存去、缓存、主存、外存。逻辑地址&#xff08;对用户角度。程序存放的位置&#xff09;、物理地…

了解和扩展Java ClassLoader

Java ClassLoader是项目开发中Java的关键但很少使用的组件之一。 就我个人而言&#xff0c;我从未在任何项目中扩展ClassLoader&#xff0c;但是拥有自己的可以自定义Java类加载的ClassLoader的想法让我感到很兴奋。 本文将概述Java类加载&#xff0c;然后继续创建自定义ClassL…

CAD教程-AL对其命令

AL可以实现不规则的对其功能 1.第一步按下AL&#xff0c;按下Enter 2.选择第一个源点 3.选择第一个目标点 4.选择第二个源点 5.选择第二个目标点 6.按下Enter&#xff0c;完成移位 转载于:https://www.cnblogs.com/weloveshare/p/4739873.html