zoukankan      html  css  js  c++  java
  • 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.0vcincvtres.exe
    C:WindowsMicrosoft.NETFrameworkv4.0.30319cvtres.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在常量区,p3在栈上。
    10     static int c=0;     //全局(静态)初始化区
    11     p1 = (char*)malloc(10);
    12     p2 = (char*)malloc(20);   //分配得来得10和20字节的区域就在堆区。
    13     strcpy(p1,"123456");   //123456放在常量区,编译器可能会将它与p3所向"123456"优化成一个地方。
    14 }

    存取效率的比較

    char s1[]="aaaaaaaaaaaaaaa";
    char *s2="bbbbbbbbbbbbbbbbb";
    aaaaaaaaaaa是在执行时刻赋值的。而bbbbbbbbbbb是在编译时就确定的;可是。在以后的存取中,在栈上的数组比指针所指向的字符串(比如堆)快。

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

    ref:


  • 相关阅读:
    redis:高可用分析
    mysql:explain分析sql
    python中注意事项(更新)
    jupyter使用小技巧(更新)
    Jupyter中的快捷键
    Excel制作甘特图
    Vim编辑器常用命令
    Mysql主从
    常用MySql命令
    进程与线程的一个简单解释
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7214441.html
Copyright © 2011-2022 走看看