C++链接和执行相关错误

http://blog.csdn.net/pipisorry/article/details/37610401

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后,就不须要每次都设置配置了。

皮皮blog



VC++的链接错误LNK2005 已经在*.obj中定义

LNK2005错误——反复定义错误

形成的原因:

1. 反复定义全局变量。

可能存在两种情况:
A、 对于一些初学编程的程序猿,有时候会以为须要使用全局变量的地方就能够使用定义申明一下。事实上这是错误的。全局变量是针对整个project的。正确的应该是在一个CPP文件里定义例如以下:int g_Test;那么在使用的CPP文件里就应该使用:extern int g_Test就可以。假设还是使用int g_Test,那么就会产生LNK2005错误,一般错误错误信息类似:AAA.obj error LNK2005 int book c?book@@3HA already defined in BBB.obj。

切记的就是不能给变量赋值否则还是会有LNK2005错误。
       这里须要的是“声明”,不是“定义”!依据C++标准的规定。一个变量是声明,必须同一时候满足两个条件,否则就是定义:
(1)声明必须使用externkeyword。(2)不能给变量赋初值
所以。以下的是声明:
extern int a;
以下的是定义
int a; int a = 0; extern int a =0;
B、对于那么编程不是那么严谨的程序猿,总是在须要使用变量的文件里任意定义一个全局变量,而且对于变量名也不予考虑,这也往往easy造成变量名反复。而造成LNK2005错误。



2. 头文件的包括反复。往往须要包括的头文件里含有变量、函数、类的定义。在其他使用的地方又不得不多次包括之,假设头文件里没有相关的宏等防止反复链接的措施,那么就会产生LNK2005错误。

解决的方法是在须要包括的头文件里做类似的处理:#ifndef MY_H_FILE   //假设未定义这个宏
#define MY_H_FILE   //定义这个宏
…….   //头文件主体内容
…….
#endif
上面是使用宏来做的,也能够使用预编译来做,在头文件里增加:
#pragma once
//头文件主体
3. 使用第三方的库造成的。这样的情况主要是C执行期函数库和MFC的库冲突造成的。详细的办法就是将那个提示出错的库放到另外一个库的前面。

另外选择不同的C函数库,可能会引起这个错误。

微软和C有两种C执行期函数库,一种是普通的函数库:LIBC.LIB。不支持多线程。第二种是支持多线程的:msvcrt.lib。假设一个project里。这两种函数库混合使用。可能会引起这个错误,普通情况下它须要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]

皮皮blog


写入位置时发生訪问冲突

原因总结:

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是在编译时就确定的;可是。在以后的存取中,在栈上的数组比指针所指向的字符串(比如堆)快。

form:http://blog.csdn.net/pipisorry/article/details/37610401

ref:


posted on 2017-07-20 20:53  yjbjingcha  阅读(1087)  评论(0编辑  收藏  举报

导航