一個疏忽引發的思考!(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.pswp.cn/news/374683.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374683.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374683.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

力扣面試題 01.08. 零矩陣

編寫一種算法&#xff0c;若M N矩陣中某個元素為0&#xff0c;則將其所在的行與列清零 代碼一思路&#xff1a; 第一次遍歷時記錄&#xff0c;用兩個布爾類型數組標記行和列中是否有0元素&#xff1b; 第二次遍歷時置零 class Solution {public void setZeroes(int[][] matr…

Java最佳實踐–字符串性能和精確字符串匹配

在使用Java編程語言時&#xff0c;我們將繼續討論與建議的實踐有關的系列文章&#xff0c;我們將討論String性能調優。 我們將專注于如何有效地處理字符串創建&#xff0c; 字符串更改和字符串匹配操作。 此外&#xff0c;我們將提供我們自己的用于精確字符串匹配的最常用算法的…

mac下開發環境常用操作與命令

【1】 修改hosts文件 vim /private/etc/hosts轉載于:https://www.cnblogs.com/zsmynl/p/4714492.html

keil里面填數據

編譯后寄存器和堆棧的內存數據可以直接寫進去的。 寄存器&#xff0c;雙擊就可以&#xff0c;注意里面是十六進制 堆棧&#xff0c;也是十六進制&#xff0c;八位的 00 00 00 00 &#xff0c;但這個是從右到左的&#xff0c;比如0x00000006 應該填 06 00 00 00 把數據取出來 取…

力扣498. 對角線遍歷

給你一個大小為 m x n 的矩陣 mat &#xff0c;請以對角線遍歷的順序&#xff0c;用一個數組返回這個矩陣中的所有元素。 代碼思路&#xff1a;以第一行和右邊最后一列作為每輪的開始元素&#xff0c;先用temp存儲&#xff0c;全部按 從左上到右下 的順序遍歷&#xff0c;但是…

調試生產服務器– Eclipse和JBoss展示

您是否編寫有錯誤的代碼&#xff1f; 不&#xff0c;當然不。 對于我們其余的確實會編寫帶有錯誤的代碼的凡人&#xff0c;我想解決一個非常敏感的問題&#xff1a;調試在生產服務器上運行的應用程序。 因此&#xff0c;您的應用程序已準備好進行部署。 單元測試全部成功&…

ubuntu server獲取并自動設置最快鏡像的方法

一&#xff0c;安裝方法1 add-apt-repository ppa:ossug-hychen/getfastmirrorapt-get install getfastmirror 如果添加了臨時源&#xff0c;這樣移除add-apt-repository --remove ppa:ossug-hychen/getfastmirror 二&#xff0c;安裝方法2 wget -O getfastmirror-master.zip h…

linux之x86裁剪移植---ffmpeg的H264解碼顯示(420、422)

在虛擬機上yuv420可以正常顯示 &#xff0c;而945&#xff08;D525&#xff09;模塊上卻無法顯示 &#xff0c;后來驗證了directdraw的yuv420也無法顯示 &#xff0c;由此懷疑顯卡不支持 &#xff0c;后把420轉換為422顯示。420顯示如下&#xff1a;/* 編譯命令&#xff1a;arm…

Spring依賴注入技術的發展

回顧Spring框架的歷史&#xff0c;您會發現實現依賴注入的方式在每個發行版中都在增加。 如果您使用該框架已經超過一個月&#xff0c;那么在這篇回顧性文章中可能不會發現任何有趣的東西。 除了Scala中的最后一個示例&#xff0c;沒有其他希望&#xff0c;這種語言在Spring中意…

JS encode decode

網上查到的全都是escape&#xff0c;和需要的編碼不是一回事&#xff0c;好不容易找到的結果 保存下來以備以后使用js對文字進行編碼涉及3個函數&#xff1a;escape,encodeURI,encodeURIComponent&#xff0c;相應3個解碼函數&#xff1a;unescape,decodeURI,decodeURIComponen…

流媒體服務器 筆記

1.sip服務器回SBC Port Unreachable 說明轉碼器接收RTCP的端口沒有打開 轉載于:https://www.cnblogs.com/luoyinjie/p/7219359.html

力扣151. 翻轉字符串里的單詞

給你一個字符串 s &#xff0c;逐個翻轉字符串中的所有 單詞 。 單詞 是由非空格字符組成的字符串。s 中使用至少一個空格將字符串中的 單詞 分隔開。 請你返回一個翻轉 s 中單詞順序并用單個空格相連的字符串。 沒思路&#xff0c;看到的官方給的&#xff0c;簡潔明了&…

Spring 3 HornetQ 2.1集成教程

通過Spring框架使用JBoss的新超高性能消息傳遞系統。 HornetQ是一個開放源代碼項目&#xff0c;用于構建多協議&#xff0c;可嵌入&#xff0c;非常高性能的集群異步消息傳遞系統。 它是用Java編寫的&#xff0c;并且可以在具有Java 5或更高版本運行時的任何平臺上運行。 Horn…

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一目了然。 轉載于:…

557. 反轉字符串中的單詞 III

給定一個字符串&#xff0c;你需要反轉字符串中每個單詞的字符順序&#xff0c;同時仍保留空格和單詞的初始順序。 class Solution {public String reverseWords(String s) {StringBuffer res new StringBuffer();int length s.length();int i 0;while(i < length){int …

休眠陷阱

我已經使用Hibernate已有一段時間了&#xff0c;當我一段時間不使用Hibernate項目時&#xff0c;發現自己犯的錯誤與上次相同。 因此&#xff0c;這是我的監視清單&#xff0c;希望對其他人也有用。 實現hashCode和equals 一般而言&#xff0c;應該始終實現這些方法&#xff…

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;當您學…

350. 兩個數組的交集 II

給你兩個整數數組 nums1 和 nums2 &#xff0c;請你以數組形式返回兩數組的交集。返回結果中每個元素出現的次數&#xff0c;應與元素在兩個數組中都出現的次數一致&#xff08;如果出現次數不一致&#xff0c;則考慮取較小值&#xff09;。可以不考慮輸出結果的順序。 來源&a…

Eclipse:如何附加Java源代碼

在Eclipse中&#xff0c;當您按Ctrl按鈕并單擊任何類名稱時&#xff0c;IDE會將您帶到該類的源文件。 這是項目中具有的類的正常行為。 但是&#xff0c;如果您也希望Java核心類具有相同的行為&#xff0c;則可以通過將Java源代碼附加到Eclipse IDE來實現。 一旦附加了源代碼&a…