Кто-нибудь знает, как исправить ошибку компиляции: 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. Какие-нибудь другие альтернативы?

Другие вопросы по тегам