任何人都知道如何修复编译错误:LNK2005? (源代码里面)

时间:2009-01-12 05:17:30

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

我在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:“class std :: list&gt;   * allocList“(?allocList @@ 3PAV?$ list @ PAUALLOC_INFO @@ V?$ allocator @ PAUALLOC_INFO @@@ std @@@ std @@ A)   已在test.obj中定义

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

2 个答案:

答案 0 :(得分:13)

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

发生的事情是您最有可能在多个编译单元(C ++源文件)中包含stdafx.h,并且每个生成的目标文件都有自己的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语句添加其他原型:< / p>

extern AllocList *allocList;

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

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

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

答案 1 :(得分:0)

我试图遵循这个article,我假设所有这些代码都要放在stdafx.h中。还有其他选择吗?