Два предложения.
Во-первых, то, что создается до main
(или эквивалентного) запуска, уничтожается после завершения main
. Вызов _CrtDumpMemoryLeaks
в конце main
может дать вам ложные срабатывания. (Или это ложные отрицания?) Деструкторы глобальных объектов еще не запущены, а atexit
обратные вызовы еще не запущены, поэтому вывод утечки будет включать в себя выделения, которые просто еще предстоит правильно освободить.
(Я подозреваю, что именно поэтому ваши глобальные объекты появляются с утечкой. Возможно, в коде нет ничего плохого, и действительно вполне возможно, что он очищается должным образом - код очистки просто еще не запустился, когда _CrtDumpMemoryLeaks
называется.)
Вместо этого вам нужно дать указание библиотеке времени выполнения вызвать для вас _CrtDumpMemoryLeaks
, в самом конце, после завершения всех обратных вызовов atexit
и деструкторов глобальных объектов. Тогда вы увидите только подлинные утечки. Этот фрагмент сделает свое дело. Придерживайтесь в начале main
:
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)|_CRTDBG_LEAK_CHECK_DF);
Во-вторых, если вышеприведенное показывает подлинные утечки из вещей, которые выполняются до main
, вы можете сделать небольшую хитрость, чтобы заставить ваш собственный код работать в значительной степени, прежде чем что-либо еще увидит. Затем вы можете установить _crtBreakAlloc
, прежде чем произойдет какое-либо распределение. Просто вставьте следующий код в собственный файл .cpp:
#include <crtdbg.h>
#ifdef _DEBUG
#pragma warning(disable:4074)//initializers put in compiler reserved initialization area
#pragma init_seg(compiler)//global objects in this file get constructed very early on
struct CrtBreakAllocSetter {
CrtBreakAllocSetter() {
_crtBreakAlloc=<allocation number of interest>;
}
};
CrtBreakAllocSetter g_crtBreakAllocSetter;
#endif//_DEBUG
(Я подозреваю, что код в сегменте инициализации компилятора может хорошо выполняться до инициализации stdin
и stdout
и т. П., И, безусловно, до того, как будут созданы какие-либо глобальные объекты, поэтому вам может быть сложно выполнить что-то более сложное, чем выше!)
(Сколько бы это ни стоило, я придерживаюсь мнения, и в течение некоторого времени я считал, что распределение до начала main
почти всегда плохо. Из-за этого трудно убирать за собой, и трудно отследить, что происходит. Это, конечно, удобно, но вы, кажется, всегда платите за это позже. Это совет, который гораздо легче раздать, чем реализовать, особенно, как часть большой команды. )