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]
這裡需要的是“宣告”,不是“定義”!根據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
MATLAB和c++混編 除錯相關內容
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型別限定關鍵字