【问题标题】:Anyone knows how to fix compile error: LNK2005? (Source Code inside)任何人都知道如何修复编译错误:LNK2005? (里面有源代码)
【发布时间】:2010-09-30 21:01:10
【问题描述】:

我在 stdafx.h 中有以下代码。

using namespace std;

typedef struct {
    DWORD   address;
    DWORD   size;
    char    file[64];
    DWORD   line;
} ALLOC_INFO;

typedef list<ALLOC_INFO*> AllocList;
//AllocList *allocList;

没有注释代码(最后一行),它编译得很好。但是当我添加注释代码时,我收到以下错误。

错误 LNK2005:“类 std::list > * allocList" (?allocList@@3PAV?$list@PAUALLOC_INFO@@V?$allocator@PAUALLOC_INFO@@@std@@@std@@A) 已经在 test.obj 中定义了

我正在使用 Visual Studio .NET 2003。有人知道这是什么以及如何解决它吗?

【问题讨论】:

    标签: c++ visual-studio visual-c++


    【解决方案1】:

    不要将定义放在头文件中,只需声明。声明指定某些东西存在,而定义实际定义它们(通过分配空间)。比如typedefextern和函数原型都是声明,而structint和函数体是定义。

    发生的情况是,您很可能将 stdafx.h 包含在多个编译单元(C++ 源文件)中,并且每个生成的目标文件都有自己的 allocList 副本。

    然后,当您将对象链接在一起时,有两个(或更多)东西称为allocList,因此出现链接错误。

    你最好声明这个变量:

    extern AllocList *allocList;
    

    在您的头文件中并定义它在 C++ 源文件的某处(例如 main.cpp):

    AllocList *allocList;
    

    这样,每个包含stdafx.h 的编译单元都会知道外部变量,但它只定义在一个编译单元中。

    根据您的进一步信息:

    我试图关注http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml,我认为所有这些代码都应该放在 stdafx.h 中。还有其他选择吗,pax?

    我的回复如下。

    我自己不会把它们放在stdafx.h 中,因为我认为这对预编译的头文件使用了一些 MS 魔法。

    制作一个单独的头文件mymemory.h 并将你的函数原型放入其中,例如(注意这里没有body):

    inline void * __cdecl operator new(
        unsigned int size,
        const char *file,
        int line);
    

    同样在该标题中,放置AddTrack()DumpUnfreed() 等的其他原型,以及#definetypedefextern 语句:

    extern AllocList *allocList;
    

    然后,在一个新文件mymemory.cpp(其中还包含#include "mymemory.h")中,将allocList 的实际定义与所有实际函数(不仅仅是原型)一起放入,并将该文件添加到您的项目中。

    然后,#include "mymemory.h" 在您需要跟踪内存的每个源文件中(可能全部)。因为头文件中没有定义,所以在链接过程中不会出现重复项,并且由于声明存在,所以也不会得到未定义的引用。

    请记住,这不会跟踪您未编译的代码(例如第三方库)中的内存泄漏,但它应该让您了解自己的问题。

    【讨论】:

      【解决方案2】:

      我试图关注这个article,我认为所有这些代码都应该放在stdafx.h 中。 pax 还有其他替代方案吗?

      【讨论】:

      • 这确实应该是对我的回答的评论(所以我会收到通知),但无论如何我都会回答。如果有一个包含 stdafx.h 的 C++ 源文件,则该代码将起作用。否则会出现链接错误——我怀疑它从未在多文件的实际安装中进行过测试。
      • 建议你给作者发邮件 (dpicco -at-cs.mun.ca) 看看他们在说什么。
      • 有关建议的修复方法,请参阅我的回答。基本上所有函数和 allocList 定义都应该在一个单独的 C++ 源文件中,您可以将函数原型和 allocList 的外部标记留在 stdafx.h 中(尽管您可能希望将它们移动到另一个头文件)。
      猜你喜欢
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      相关资源
      最近更新 更多