Кто-нибудь знает, как исправить ошибку компиляции: LNK2005? (Исходный код внутри)
У меня есть код ниже в 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. Кто-нибудь знает, что это такое и как это решить?
2 ответа
Не помещайте определения в заголовочные файлы, просто объявления. Объявления указывают, что что-то существует, в то время как определения фактически определяют их (выделяя пространство). Например typedef
, extern
и прототипы функций - это все объявления, в то время как struct
, int
и функциональные тела являются определениями.
Происходит то, что вы, скорее всего, включаете 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. Любые другие альтернативы, чел?
Мой ответ следующий.
Я бы их не положил stdafx.h
сам, так как я думаю, что использует некоторую магию MS для предварительно скомпилированных заголовков.
Сделайте отдельный заголовочный файл mymemory.h
и поместите в нее прототипы вашей функции, например (обратите внимание, что в ней нет тела):
inline void * __cdecl operator new(
unsigned int size,
const char *file,
int line);
Также в этом заголовке поместите другие прототипы для AddTrack()
, DumpUnfreed()
и т. д., и #define
, typedef
а также extern
заявления:
extern AllocList *allocList;
Затем в новом файле mymemory.cpp
(который также содержит #include "mymemory.h"
), поставьте актуальное определение allocList
вместе со всеми реальными функциями (не только с прототипами) и добавьте этот файл в свой проект.
Затем, #include "mymemory.h"
в каждом исходном файле, в котором вам нужно отслеживать память (вероятно, все они). Поскольку в заголовочном файле нет определений, вы не получите дубликаты во время ссылки, а поскольку объявления есть, вы также не получите неопределенные ссылки.
Имейте в виду, что это не будет отслеживать утечки памяти в коде, который вы не компилируете (например, сторонние библиотеки), но он должен сообщать вам о ваших собственных проблемах.
Я пытался следовать этой статье, я предполагаю, что весь этот код предназначен для размещения в stdafx.h. Какие-нибудь другие альтернативы?