1. 程式人生 > >C++連結和執行相關錯誤

C++連結和執行相關錯誤

LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞

錯誤:

在更新VS2010,或者解除安裝VS2012安裝2010後,建立Win32 Console Project/MFC專案時會出現"LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞"的錯誤:

1>正在編譯資源...
1>正在編譯資源清單...
1>正在連結...
1>LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞
1>生成日誌儲存在
解決方案:
第一步:
將 專案——專案屬性——配置屬性——聯結器——清單檔案——嵌入清單 “是”改為“否”。
若還不能解決問題進入第二步:


第二步:檢視計算機是否為64bit作業系統,如是,繼續如下操作。
查詢是否有兩個cvtres.exe。
C:\Program Files(x86)\Microsoft Visual Studio 10.0\vc\bin\cvtres.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\cvtres.exe
右鍵屬性—詳細資訊, 檢視兩者版本號,刪除/重新命名較舊的版本,或者重新設定Path變數。
治本的辦法是第二步,刪除舊版本的cvtres.exe後,就不需要每次都設定配置了。

VC++的連結錯誤LNK2005 已經在*.obj中定義

LNK2005錯誤——重複定義錯誤

形成的原因:

1. 重複定義全域性變數。可能存在兩種情況:
A、 對於一些初學程式設計的程式設計師,有時候會以為需要使用全域性變數的地方就可以使用定義申明一下。其實這是錯誤的,全域性變數是針對整個工程的。正確的應該是在一個CPP檔案中定義如下:int g_Test;那麼在使用的CPP檔案中就應該使用:extern int g_Test即可,如果還是使用int g_Test,那麼就會產生LNK2005錯誤,一般錯誤錯誤資訊類似:AAA.obj error LNK2005 int book c?[email protected]
@3HA already defined in BBB.obj。切記的就是不能給變數賦值否則還是會有LNK2005錯誤。
       這裡需要的是“宣告”,不是“定義”!根據C++標準的規定,一個變數是宣告,必須同時滿足兩個條件,否則就是定義:
(1)宣告必須使用extern關鍵字;(2)不能給變數賦初值
所以,下面的是宣告:
extern int a;
下面的是定義
int a; int a = 0; extern int a =0;
B、對於那麼程式設計不是那麼嚴謹的程式設計師,總是在需要使用變數的檔案中隨意定義一個全域性變數,並且對於變數名也不予考慮,這也往往容易造成變數名重複,而造成LNK2005錯誤。

2. 標頭檔案的包含重複。往往需要包含的標頭檔案中含有變數、函式、類的定義,在其它使用的地方又不得不多次包含之,如果標頭檔案中沒有相關的巨集等防止重複連結的措施,那麼就會產生LNK2005錯誤。解決辦法是在需要包含的標頭檔案中做類似的處理:#ifndef MY_H_FILE   //如果沒有定義這個巨集
#define MY_H_FILE   //定義這個巨集
…….   //標頭檔案主體內容
…….
#endif
上面是使用巨集來做的,也可以使用預編譯來做,在標頭檔案中加入:
#pragma once
//標頭檔案主體
3. 使用第三方的庫造成的。這種情況主要是C執行期函式庫和MFC的庫衝突造成的。具體的辦法就是將那個提示出錯的庫放到另外一個庫的前面。另外選擇不同的C函式庫,可能會引起這個錯誤。微軟和C有兩種C執行期函式庫,一種是普通的函式庫:LIBC.LIB,不支援多執行緒。另外一種是支援多執行緒的:msvcrt.lib。如果一個工程裡,這兩種函式庫混合使用,可能會引起這個錯誤,一般情況下它需要MFC的庫先於C執行期函式庫被連結,因此建議使用支援多執行緒的msvcrt.lib。所以在使用第三方的庫之前首先要知道它連結的是什麼庫,否則就可能造成LNK2005錯誤。如果不得不使用第三方的庫,可以嘗試按下面所說的方法修改,但不能保證一定能解決問題,前兩種方法是微軟提供的:
A、 選擇VC選單Project->Settings->Link->Catagory選擇Input,再在Ignore libraries 的Edit欄中填入你需要忽略的庫,如:Nafxcwd.lib;Libcmtd.lib。然後在Object/library Modules的Edit欄中填入正確的庫的順序,這裡需要你能確定什麼是正確的順序,呵呵,God bless you!
B、 選擇VC選單Project->Settings->Link頁,然後在Project Options的Edit欄中輸入/verbose:lib,這樣就可以在編譯連結程式過程中在輸出視窗看到連結的順序了。
C、 選擇VC選單Project->Settings->C/C++頁,Catagory選擇Code Generation後再在User Runtime libraray中選擇MultiThread DLL等其他庫,逐一嘗試。
關於編譯器的相關處理過程,參考:
http://www.donews.net/xzwenlan/archive/2004/12/23/211668.aspx

4.在用第三方庫時,由於errno被重定義,用多種方法都不能解決,後查詢MSDN,發現link有個選項/FORCE可以解決,在IDE下
Project->Settings->Link頁,選categroy為custom,將force file output前打勾
但會有警告
warning LNK4088: image being generated due to /FORCE option; image may not run

但的確解決了問題,這是由於VC對重定義比較嚴格,像BCB或GCC在庫中的重定義不會有任何警告或錯誤

5.另外一個出現LINK2005的現象,好像是由於名稱空間而引起的。我在dos下寫的程式沒有問題,但是放在mfc中就出現了這個連結錯誤。因為起初圖省事,我在一個頭檔案中寫了using namespace std,並且這個標頭檔案我多處使用,另外,我還使用了boost庫。後來,問題解決的方法非常奇怪,在一個頭檔案中引用其他標頭檔案,這些標頭檔案的順序換一下就通過了,那個出現問題的標頭檔案中我使用了std::map,當我把這種容器使用模板代替後,連結就有沒事了。(例如:template<class coll>),後來感到模板技術還有這種效果

ps:這種情況好像就是因為庫的版本衝突造成的。標準的C++庫使用C執行期函式庫。MFC使用了自己的C執行期函式庫。調整標頭檔案的順序也就是調整連結庫的順序。在這種情況下一般是將MFC的執行期庫放在前面即可!

6.#pragma comment( linker, "/NODEFAULTLIB:msvcprtd.lib" )
#pragma comment( linker, "/NODEFAULTLIB:libcmtd.lib" )
#pragma comment( linker, "/NODEFAULTLIB:msvcprt.lib" )
#pragma comment( linker, "/NODEFAULTLIB:libcmt.lib" )

#ifdef _UNICODE
  #pragma comment( linker, "/ENTRY:wWinMainCRTStartup" )
#endif

#ifdef _DEBUG
  #pragma comment( lib, "cryptlibd" )
#else
  #pragma comment( lib, "cryptlib" )
#endif

7.我的解決:

static char * strReverse(char *str);

引入的.cpp或,h檔案中的函式前面加上static,執行成功!!!

[http://bbs.csdn.net/topics/70346371]

寫入位置時發生訪問衝突

原因總結:

1:使用了未初始化的指標(未給指標分配空間)

2:使用了已經刪除的指標

3.char str[]="ABCD",這個陣列的儲存空間是在棧中開闢的(在棧中開闢了一個數組?)

char *str="ABCD",str指向的是靜態儲存區,"ABCD"是位於常量區的,指標str只是指向了這個位置(只在棧中開闢了一個指標記憶體?),那麼這些值就不能被修改。而上面陣列中,要注意的是把字元複製到陣列的元素中,那麼就是可以被任意修改的。

例:

char* str = "ABCD"; //char str[] = "ABCD";可以解決
strrev(str);
char * strrev(char str[]){
int j, i;
for(i = 0, j = strlen(str) - 1; i < j; i++, j--){
char tmp = str[i];
str[i] = str[j];//寫入位置時發生衝突
str[j] = tmp;
}
return str;
}
分析:

程式程式碼區:

 1 //main.cpp
 2 int a=0;    //全域性初始化區
 3 char *p1; //全域性未初始化區
 4 main()
 5 {
 6     int b;                  //棧
 7     char s[]="abc";  //棧
 8     char *p2;           //棧
 9     char *p3="123456";   //123456\0在常量區,p3在棧上。
10     static int c=0;     //全域性(靜態)初始化區
11     p1 = (char*)malloc(10);
12     p2 = (char*)malloc(20);   //分配得來得10和20位元組的區域就在堆區。
13     strcpy(p1,"123456");   //123456\0放在常量區,編譯器可能會將它與p3所向"123456"優化成一個地方。
14 }

存取效率的比較

char s1[]="aaaaaaaaaaaaaaa";
char *s2="bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在執行時刻賦值的;而bbbbbbbbbbb是在編譯時就確定的;但是,在以後的存取中,在棧上的陣列比指標所指向的字串(例如堆)快。

ref:

相關推薦

C++連結執行相關錯誤

LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞 錯誤: 在更新VS2010,或者解除安裝VS2012安裝2010後,建立Win32 Console Project/MFC專案時會出現"LINK : fatal erro

C/C++——程式實現過程之編譯、連結執行

從寫一個簡單的“hello world!”到完成一個大型程式,當程式從編輯完成到執行成功都會經過5個步驟,分別是預處理(Prepressing)、編譯(Compilation)、彙編(Assembly)、連結(Linking)和執行(Executing)。瞭解這五個過程中所

c++中的編譯、連結執行

1.編譯與連結的區別: 預處理:處理巨集定義指令#define 、標頭檔案#include等 #include<filename> ,尖括號表示系統提供的標頭檔案,直接去系統目錄查詢; #include“animal.h”,雙引號表示自己編寫的標頭檔案,

.net C# web程式執行錯誤日誌寫入文字檔案中

網上找的原始碼,自己根據實際情況進行了修改,能將日誌儲存在發不出來的web程式根目錄下的ErrorLog資料夾內。 #region 建立錯誤日誌 ///-------------------------------------

深入編譯連結執行

我們先看下面這份程式碼: #include<stdio.h> int gdata1=10; int gdata2=0; int gdata3; static int gdata4=11;

excel 不能使用物件連結嵌入的錯誤

     最近excel在開啟時出現 不能使用物件連結和嵌入 的錯誤(英文為:Cannot use object linking and embedding.),嘗試修復、重灌office、excel都未能解決,最後在網上查資料都說是因為病毒引起(被蠕蟲感染),於是基本上打上

editplus配置C/C++編譯執行環境的方法

editplus下載地址:密碼:kku6gcc編譯器下載地址:密碼:cphi1.首先是配置gcc環境變數右擊計算機--屬性--左側高階系統設定--高階--環境變數--系統變數--path--編輯--在最後將minGW或gcc的安裝目錄下的bin路徑新增進去。例如 D:\min

JAVA的編譯時錯誤執行錯誤

1. 要區分編譯時錯誤和執行時錯誤,就應該先明白什麼是編譯?什麼是執行? 首先,先看一下這張圖: 編譯期就是將我們寫的java原始碼交給編譯器執行的過程,起翻譯的作用,該過程主要對java原始碼的語法進行檢查,如果沒有語法錯誤,就將原始碼編譯成位元組

C# 集合類Dictionary的遍歷修改(防止錯誤:集合已修改;可能無法執行列舉操作。)

       C#中直接對集合Dictionary進行遍歷並修改其中的值,會報錯,如下程式碼就會報錯:集合已修改;可能無法執行列舉操作。程式碼如下 public void ForeachDic() { Dictionary<String, In

C++中有關volatile關鍵字的作用--阻止編譯器將其變數優化快取到暫存器(執行相關)(轉自百度)

       就象大家更熟悉的const一樣,volatile是一個型別修飾符(type specifier)。        它是被設計用來修飾被不同執行緒訪問和修改的變數 。        如果沒有volatile,基本上會導致這樣的結果:要麼無法編寫多執行緒

C# WebBrowser控制元件禁用超連結轉向、指令碼錯誤提示、預設右鍵選單快捷鍵

1. 禁用錯誤指令碼提示 將 WebBrowser控制元件的 ScriptErrorsSuppressed 設為 true 2. 禁用右鍵選單: 將 WebBrowser 的 IsWebBrowserContextMenuEnabled 設為 false 3. 禁用快

C程序的執行當前進程的結束

結束進程 csharp log 取消 main函數 sha atexit 註冊 歷程 內核使程序執行的唯一方法,就是調用exec函數,這個函數又會啟動一個C程序啟動例程,這個啟動例程是C程序的啟動地址。負責調用main函數,並接受mainn函數的返回值。 使得進程結束的

C#異步執行帶有返回值參數的方法,且獲取返回值

urn 利用 回調方法 ext col list ont mes gate 很多時候需要用到這些小知識點,做做筆記一起成長 下面是需要異步執行的方法 //獲取所有的郵件 private List<EmailModel> GetEmailOnl

C語言獲取執行文件(XXX.exe)文件名目錄路徑

color lan .net director blank Go 執行 pause sys 同CSDN上的 https://blog.csdn.net/Higashino_Keigo/article/details/80489874 C語言獲取執行文件(XXX.exe)文件

C#需要在項目程序生成前後執行相關的事件

先生 style .com alt mkdir bug fff 分享圖片 color 分享4: 需求:需要在項目程序生成前後執行相關的事件,比如:需要將某個文件拷貝到bin\Debug中,或者創建某文件夾等。 分析:我們可利用項目屬性

【轉載】一個c程序在執行main函數之前main之後都做了那些事情

loss -- text ould 很多 int win 部分 不知道 轉自:https://bbs.csdn.net/topics/300103318#r_78088969 main函數之前--真正的函數執行入口或開始一種解釋實際上,在可執行文件被加載之後,控制權立即交給

Linux環境下c程序的編譯執行

環境變量 動態 main.c tor direct 環境 沒有 stdlib.h share 1 單個文件的編譯和執行創建main.c文件,內容如下: #include <stdio.h> #include <stdlib.h> int main

MATLABc++混編 除錯相關內容

https://wenku.baidu.com/view/6fd2cf55cfc789eb162dc857.html?qq-pf-to=pcqq.c2c   原網址 在Matlab 中除錯用C/C++編寫的MEX 檔案(32、64位機,VS2005和matlab R2010b) mex

Linux環境下c程式的編譯執行

1 單個檔案的編譯和執行建立main.c檔案,內容如下: #include <stdio.h> #include <stdlib.h> int main(void){ printf("Hello world!\n"); return 0; };   編譯:

C儲存類、連結記憶體管理--動態分配記憶體及型別限定詞

文章目錄 儲存類說明符 儲存類和函式 動態分配記憶體 `malloc`函式 `free`函式 `calloc`函式 動態分配記憶體的缺點 C型別限定關鍵字