Http://www-d0.fnal.gov/d0dist/dist/releases/development/l3xDAQSuper/src/debug_utils/Source/memory_leak_checker.cpp
//
// Memory_leak_checker.cpp
//
// This guy's constructor will start leak checking and when
// Its destructor is called it will print out error messages
// If there is any memory that has been allocated.
//
# Include "memory_leak_checker.hpp"
# Include <iostream>
# Include <crtdbg. h>
# Include <windows. h>
//
// Memory_leak_checker
//
// Cache our state
//
Memory_leak_checker: memory_leak_checker (void)
# Ifdef _ debug
: _ Memory_state (New _ crtmemstate), _ filename_valid (false)
# Else
: _ Memory_state (0)
# Endif
{
# Ifdef _ debug
//
// Turn on leek checking
//
_ Old_tracking_flags = _ crtsetdbgflag (_ crtdbg_report_flag | _ crtdbg_leak_check_df); // turn on leak-checking bit
//
// Remember what the memory stuff looks like
//
_ Report_mode_warn = _ crtsetreportmode (_ crt_warn, _ crtdbg_mode_file );
_ Report_mode_error = _ crtsetreportmode (_ crt_error, _ crtdbg_mode_file );
_ Report_mode_assert = _ crtsetreportmode (_ crt_assert, _ crtdbg_mode_file );
_ Report_file_warn = _ crtsetreportfile (_ crt_warn, _ crtdbg_file_stdout );
_ Report_file_error = _ crtsetreportfile (_ crt_error, _ crtdbg_file_stdout );
_ Report_file_assert = _ crtsetreportfile (_ crt_assert, _ crtdbg_file_stdout );
_ Crtmemcheckpoint (_ memory_state );
# Endif
}
//
// Set_file
//
// Set the output file
//
Void memory_leak_checker: set_file (const char * filename, bool append)
{
Unsigned int create_flags = create_always;
If (append ){
Create_flags = open_always;
}
_ Filename_handle =: createfile (filename, generic_write, 0, 0, create_flags, file_attribute_normal, 0 );
_ Filename_valid = _ filename_handle! = Invalid_handle_value;
If (_ filename_valid ){
//
// Get to the end of the file
//
: Setfilepointer (_ filename_handle, 0, 0, file_end );
//
// Set up the various report handles
//
_ Crtsetreportfile (_ crt_warn, _ filename_handle );
_ Crtsetreportfile (_ crt_error, _ filename_handle );
_ Crtsetreportfile (_ crt_assert, _ filename_handle );
}
}
//
//~ Memory_leak_checker
//
// Restore everything and print out the current state
// The Memory heap.
//
Memory_leak_checker ::~ Memory_leak_checker (void)
{
# Ifdef _ debug
//
// See if there is any difference between now and then.
//
_ Crtmemstate state_now;
_ Crtmemcheckpoint (& state_now );
_ Crtmemstate the_difference;
If (_ crtmemdifference (& the_difference, _ memory_state, & state_now )){
STD: cout <"***" <STD: Endl <"*** Memory Leak seen! "<STD: Endl <" *** "<STD: Endl;
_ Crtmemdumpstatistics (& the_difference );
_ Crtmemdumpallobjectssince (_ memory_state );
}
Delete _ memory_state;
//
// Reset the memory tracking flags
//
_ Crtsetdbgflag (_ old_tracking_flags );
//
// Reset the Error Reporting
//
_ Crtsetreportmode (_ crt_warn, _ report_mode_warn );
_ Crtsetreportmode (_ crt_error, _ report_mode_error );
_ Crtsetreportmode (_ crt_assert, _ report_mode_assert );
_ Crtsetreportfile (_ crt_warn, _ report_file_warn );
_ Crtsetreportfile (_ crt_error, _ report_file_error );
_ Crtsetreportfile (_ crt_assert, _ report_file_assert );
//
// Close a file if we have it open
//
If (_ filename_valid ){
: Closehandle (_ filename_handle );
}
# Endif
}
//
// Break_on_block
//
// Cause a debugger break point when a certian block is allocated.
//
Void memory_leak_checker: break_on_block (long block_number)
{
# Ifdef _ debug
_ Crtsetbreakalloc (block_number );
_ Crtbreakalloc = block_number;
# Endif
}