如果C語言程序在一台電腦上可以運行,到另外一台就運行出問題是什麼原因?
- 新手最常遇到的問題就是直接拿著debug版去別人電腦上用了, 別人電腦上沒有vs或者沒有相同版本的vs, 找不到debug版本依賴的庫, 所以打不開.
1.5 對方可以打開你的debug版, 然而被殺毒軟體殺了.
- 新手第二大的問題就是是release版, 但選擇了錯誤的Runtime Library載入方式, 就是那堆什麼 MT那個MD... 選擇動態載入時如果對方系統沒有安裝特定版本的運行庫則會打不開( 你要問為什麼商業軟體沒這問題, 那是因為商業軟體要麼靜態鏈接,要麼在安裝時把它自己依賴的運行庫都給裝了. )
- 新手第三大的問題和第二個有點相似, 就是寫出來的程序本身或依賴一些第三方的dll. 載入dll要麼跟程序在同目錄, 要麼在系統目錄, 要麼指定一個目錄. 有些構建系統可能替用戶在他的電腦上搞定了這個事了. 而他人電腦中並沒有這個dll, 或者有這個dll但是版本不對. 所以打不開.
- 新手第四大的問題是寫死了一些文件路徑, 例如假定對方一定有C盤之類的操作, 又沒有正確處理文件打開失敗時的錯誤處理. 所以掛了.
- 新手第五大的問題是執行了一些在操作系統看來需要申請許可權的操作, 例如讀取註冊表, 訪問敏感目錄等. 而卻沒有正確調用申請許可權的方法, 而自己電腦上UAC是關閉的, 所以沒發現問題. 別人電腦上UAC是開著的, 所以打不開.
- 新手第六大的問題是編譯的是64位版本程序, 而對方電腦是32位系統.
- 新手第七大的問題是, 使用比較高的VS版本時, 它的運行庫默認已經不支持老系統了(主要是XP). 而別人系統較老, 所以打不開.
- 新手第八大的問題是, 程序里可能意外調用了一些很新的系統才有的windows API或者動態調用了其他諸如intrinsic之類的玩意, 或者意外使用了非常新的CPU指令集.... 不過能到這一步基本已經不是新手了....... 為什麼掛了心裡應該還是有點逼數的.
- 當bug遇上系統版本/內存大小等等非常細微不可名狀的區別時, bug的行為可能會不同, 這確實可能導致在某台機器上很容易對, 而另一台機器上不容易對. 例如我確實遇到過一個bug, 是在我的程序的某一段里有個小bug會把一個指針的特定某幾位清零. 而在我電腦上運行時, 這運行到那裡時那個指針總是能拿到一個地址比較固定的內存, 那被清零的幾位100次里有至少95次正好本來就是0. 而另一台機器上卻100次里可能只有1次能對. 我也不知道為什麼, 就是這麼巧.
- 再往後就被摧殘習慣了, 就不是新手了......
你就不會用 WinDBG / gdb 調試下嗎?
只要分為兩種情況了:
- 是在一個電腦上編譯好之後,拷貝到不同的電腦上運行?
- 還是源程序,在不同電腦上分別編譯運行?
如果在一台電腦上編譯好之後,拷貝到另外一台電腦上運行出了問題:此時就要看兩台電腦的CPU架構是否一樣,是不是都是X86或ARM架構?是不是在64環境下編譯,然後拷貝到了32位的環境下去運行?
如果是源程序拷貝到另外一台電腦上編譯運行,結果不同。那就要看程序本身和編譯器的問題了:你的程序中是否使用了一些跟平台相關的C語言特性、編譯器特性等等。
即使在同一編譯器的計算機上,也有庫不一樣,實現方法不一樣,更別提不同編譯器產生的不同可執行文件了。這也是c語言最大的弱點。
use docker
僅限於簡單程序:
1。gcc編譯的添加-static選項
2。用vs的切換到release選項再編譯
1.系統不一樣
比如windows的程序當然不能(wine不算)在linux上直接運行.
2.缺少依賴
比如開發機器A上有所需的運行庫,但在複製到機器B上時未一同複製.
3.配置缺失/錯誤
可能目標機器上缺少程序初始化所需的配置,或是存在錯誤的配置.
底層依賴庫不一致
C語言不是目標級兼容語言,所以你可能會面對下面幾種情況
- 操作系統不一樣,比如Windows和Linux之間沒法直接拷貝運行
- 目標處理器架構不一樣,x86,ARM,MIPS之間無法直接運行,需要交叉編譯
- 相同處理器64位和32位會存在一定的兼容問題,需要重新編譯
- 有可能你只拷貝的執行文件,但是他還需要依賴一些動態庫,因為不是所有編譯都採用靜態鏈接
先假設個沒有低級錯誤,
個人認為較大可能是因為編譯器不同導致的部分細節不一致,
標準庫對許多細節並沒有規定,所以不同平台的編譯器有可能得出不同結果,
如果這個結果還很關鍵的話就理所當然地炸掉了。
再補充一下,面向32位架構的寫出的源碼編譯成64位程序時也可能會出問題。
以上都是針對源代碼,不過仔細想想感覺題主問的貌似是可執行程序。
可以考慮一下這幾個問題:
- 缺少runtime。(一般情況下都會報錯缺少xxx.dll)
- 處理器指令體系不兼容。(Windows貌似沒有這個問題)
- 操作系統不支持64位應用程序。(我還真沒試過把64位程序放到32位操作系統上)
- 其他源代碼內部的問題。(這就算是BUG了吧)
題主這個問題,,,基本全靠猜。。。
主要問題是缺庫,你調用的,是你自己裝的,其他同類型系統,默認沒有。養成好習慣,庫自己寫,系統API盡量不用,以後基本不會出現這種問題了。你要是犯Linux與win不通用這種小白的錯誤,還是回去重修或者轉行吧。
我之前遇到過一次 我是數組越界了。這台電腦上越界的地方是空的,就沒報錯,到另一台電腦上越界的地方存有其他數據,就會報錯。
多種情況
1.該程序依賴特定外部文件、外部程序、外部環境變數、操作系統版本、機器架構,而B上不具備
2.該程序內存訪問異常,A環境上未表現,B環境表現出來了
3.該程序由多個依賴的二進位程序和/或數據文件構成,包括共享庫,資源文件,可執行文件。但該程序拷貝到B環境不完整。
4.B環境未能提供足夠系統資源,包括內存,顯存,外存等,程序未報告該異常放棄執行。
5.B環境存在故障
6.程序本身帶有硬體ID識別能力,只能在特定機器ID上執行
A環境指可正確執行的環境,B環境指出錯環境。具體視錯誤信息和程序功能而定。
推薦閱讀: