Как использовать Верификатор Приложения для нахождения утечек памяти

Я хочу найти утечки памяти в своем приложении с помощью стандартных утилит. Ранее я использовал свое собственное средство выделения памяти, но другие люди (да, Вы AlienFluid) предложили использовать Верификатор Приложения Microsoft, но я, может казаться, не заставляю это сообщать о моих утечках. У меня есть следующее простое приложение:

#include <iostream>
#include <conio.h>

class X
   {
   public:
      X::X() : m_value(123) {}
   private:
      int m_value;
   };

void main()
{
X *p1 = 0;
X *p2 = 0;
X *p3 = 0;

p1 = new X();
p2 = new X();
p3 = new X();
delete p1;
delete p3;
}

Этот тест ясно содержит утечку памяти: p2 является new'd, но не удаленный.

Я создаю исполняемый файл с помощью следующих командных строк:

cl /c /EHsc /Zi /Od /MDd test.cpp
link /debug test.obj

Я загрузил Верификатор Приложения (4.0.0665) и включил все проверки.

Если я теперь работаю, мое тестовое приложение I видит журнал его в Верификаторе Приложения, но я не вижу утечку памяти.

Вопросы:

  • Почему Верификатор Приложения не сообщает об утечке?
  • Или Верификатор Приложения действительно не предназначается для нахождения утечек?
  • Если это не, который другие инструменты доступны для ясного создания отчетов об утечках в конце приложения (т.е. не путем взятия обычных снимков и сравнения их, так как это не возможно в приложении, берущем 1 ГБ или больше), включая стек вызовов места выделения (так не простая утечка, сообщающая в конце CRT)

Если я не нахожу достойную утилиту, я все еще должен полагаться на своего собственного диспетчера памяти (который делает это отлично).

9
задан Patrick 2 June 2010 в 07:52
поделиться

3 ответа

Обнаружение утечек памяти CRT (без трассировки стека):

// debug_new.h
#pragma once

#include "crtdbg.h"

#ifdef _DEBUG
#ifndef DEBUG_NEW
#define DEBUG_NEW   new( _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif

Все .cpp файлы:

#include "debug_new.h"

...

// After all other include lines:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

...

Напишите это один раз в коде инициализации программы:

_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

В MFC все это уже реализовано в заголовках MFC. Вам нужно только убедиться, что каждый файл cpp содержит эти строки:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Ограничения: это ловит только "новые" утечки памяти, все утечки, вызванные другими функциями, такими как malloc, не ловятся.

Не делайте никаких выделений внутри .h файлов - они будут выведены без исходных строк, потому что DEBUG_NEW определен после всех строк #include.

4
ответ дан 4 December 2019 в 21:08
поделиться

У меня такое ощущение, что Application Verifier специально рассматривает путь выхода и не отмечает эти утечки как утечки - в конце концов, вся куча процесса освобождается при его выходе.

Попробуйте написать другой пример, где вы снова инициализируете тот же указатель - по сути, теряете ссылку на предыдущее выделение. Это, конечно, должно быть отмечено. Сообщите мне о результатах.

Кроме того, AppVerifier (если у вас включены все опции) должен также отлавливать переполнения буфера, недополнения, запись в места стека, помеченные RO и т.д.

1
ответ дан 4 December 2019 в 21:08
поделиться

Простейшим решением является не записывать утечки или переполнения буфера в первую очередь - обнаружение их после события действительно является пустой тратой усилий. В моем собственном коде в течение многих лет у меня не было проблем в этих областях. Почему? Потому что я использую механизмы, которые предоставляет C ++, чтобы их избежать. Например:

X *p1 = 0;
p1 = new X();

должно быть:

shared_ptr <X>  p1 = new X();

, и вы больше не беспокоитесь об утечке p1. Еще лучше вообще не использовать динамическое распределение:

X x1;

Для переполнения буфера всегда используйте такие типы, как std :: string, которые будут увеличиваться при вводе, или, если они не увеличиваются, обнаружат возможное переполнение и предупредит вас.

Я не хвастаюсь своим умением избегать утечек памяти - это действительно работает и позволяет вам справляться с гораздо более сложной задачей отладки бизнес-логики вашего кода.

0
ответ дан 4 December 2019 в 21:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: