Начиная с написания этих «пустых» функций. Они заменят стандартные новые и удалят ваши самостоятельно:
void *operator new (size_t memorySize);
void *operator new[] (size_t memorySize);
void *operator new (size_t memorySize, const std::nothrow_t &) throw ();
void *operator new[] (size_t memorySize, const std::nothrow_t &) throw ();
void operator delete (void *memoryPointer);
void operator delete[] (void *memoryPointer);
void operator delete (void *memoryPointer, const std::nothrow_t &) throw ();
void operator delete[] (void *memoryPointer, const std::nothrow_t &) throw ();
Затем напишите отдельные функции для выделения и освобождения памяти:
void *myNew (size-t memorySize);
void myDelete (void *memoryPointer);
Позвоните myNew и myDelete в функции, упомянутые в начале.
Реализация myNew и myDelete с использованием HeapAlloc и HeapFree.
Затем создайте глобальную переменную и пометьте ее так (это Visual Studio):
#pragma init_seg(lib)
Это будет гарантировать, что ваша глобальная переменная инициализируется первой, а очищается последней.
Пока мы рассмотрели основы. Чтобы получить реальную функциональность отчетов об утечках, вам нужно будет хранить информацию о выделенной памяти в вашей функции myNew.
Используйте деструктор вашей глобальной переменной, чтобы сообщить обо всех утечках.
Кроме того, вы можете использовать StackWalk для получения стека вызовов, а также сохранять его при каждом выделении памяти.
Некоторые, вероятно, задаются вопросом, почему вы хотите сделать это вместо использования других инструментов:
- По моему опыту, отчеты об утечках в Visual Studio ограничены. Он не показывает вам стек вызовов, а только прямой вызов, что делает его бессмысленным.
- некоторые инструменты используют #define для замены new, delete, alloc, ..., но в некоторых случаях это может вызвать проблемы (например, метод класса, который вызывается free (видел это в Qt), или удаление выполняется) в заголовке, но новый в .lib, который должен быть связан (также видно в Qt)).
- другие инструменты требуют, чтобы вы делали интерактивные снимки своего приложения и впоследствии сравнивали их. В моем подходе, приведенном выше, вы получаете автоматическое сообщение об утечке (никаких действий вручную не требуется, всегда в конце приложения, ...).
Когда у вас есть собственный менеджер памяти, вы можете начать думать о добавлении других функций (например, статистика памяти на основе стека вызовов, приемы поиска перезаписи памяти, приемы поиска кода, который повторно использует память после ее удаления, .).