2009-01-12 83 views
2

我在stdafx.h中有下面的代碼。任何人都知道如何修復編譯錯誤:LNK2005? (源代碼裏面)

using namespace std; 

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

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

沒有評論的代碼(最後一行),它編譯得很好。但是當我添加評論的代碼時,我得到以下錯誤。

error LNK2005: "class std::list > * allocList" ([email protected]@[email protected][email protected]@[email protected][email protected]@@[email protected]@@[email protected]@A) already defined in test.obj

我正在使用Visual Studio .NET 2003.任何人都有任何想法是什麼以及如何解決它?

回答

13

請勿將的定義置於頭文件中,只需聲明。聲明指定某些東西存在,而定義實際上定義了它們(通過分配空間)。例如typedef,extern和函數原型都是聲明,而類似struct,int和函數體是定義。

發生了什麼事情是,你很可能包含多個編譯單元(C++源文件)中的stdafx.h,並且每個生成的目標文件都獲得它自己的副本allocList

然後,當您將這些對象鏈接在一起時,會有兩個(或多個)事件,稱爲allocList,因此鏈接錯誤。

你會好起來聲明變量:

extern AllocList *allocList; 

在你的頭文件和定義它的地方,在C++源文件(如main.cpp):

AllocList *allocList; 

這樣,包含stdafx.h的每個編譯單元都將知道外部變量,但它只在一個編譯單元中定義。根據您的詳細信息

I was trying to follow http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml , I assume that all those code are meant to be placed in the stdafx.h. Any other alternatives, pax?

我的回答如下。

我不會把它們放在stdafx.h之內,因爲我認爲它使用了一些MS魔術來預編譯頭文件。

製作一個單獨的頭文件mymemory.h,並把你的函數原型在裏面,例如(注意,這沒有):

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"在你需要跟蹤內存的每個源文件中(可能都是這些文件)。由於頭文件中沒有定義,因此在鏈接期間不會出現重複內容,並且因爲聲明存在,所以您也不會收到未定義的引用。

請記住,這不會跟蹤您不編譯的代碼(例如第三方庫)中的內存泄漏,但它應該讓您知道您自己的問題。

0

我試圖按照這個article,我認爲所有這些代碼都是要放在stdafx.h中。任何其他替代辦法?

+2

這應該是我的回答(所以我得到通知)的評論,但無論如何我都會回答。如果只有一個包含stdafx.h的C++源文件,那麼該代碼就可以工作。否則,它會得到鏈接錯誤 - 我懷疑它從來沒有在多文件實際安裝中測試過。 – paxdiablo 2009-01-12 05:40:35

相關問題