Listing 2: AppWatchMan.cpp

// Definition for Application Watch Man Class Functions
#include <time.h>
#include <iostream.h>
#include <fstream.h>
#include <stdarg.h>
#include <malloc.h>
#include <crtdbg.h>
#include <memory.h>
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <string>
#include "AppWatchMan.h"

using namespace std;

// Since _Crt functions are only compiled if _DEBUG
#ifdef   _DEBUG
  const bool AppWatchMan::m_bOnDuty = true;
#else
  const bool AppWatchMan::m_bOnDuty = false;
#endif

AppWatchMan::AppWatchMan() : m_pStrLog(&cout)
{
  if ( m_bOnDuty )
  {
    ios::sync_with_stdio();

    _CrtSetReportMode(_CRT_WARN,   _CRTDBG_MODE_FILE );
    _CrtSetReportFile(_CRT_WARN,   _CRTDBG_FILE_STDOUT);
    _CrtSetReportMode(_CRT_ERROR,  _CRTDBG_MODE_FILE );
    _CrtSetReportFile(_CRT_ERROR,  _CRTDBG_FILE_STDOUT);
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE );
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);

    memset((void *)&m_stFirst,    0, sizeof(m_stFirst));
    memset((void *)&m_stPrevious, 0, sizeof(m_stPrevious));
    memset((void *)&m_stLast,     0, sizeof(m_stLast));
    memset((void *)&m_stDiff,     0, sizeof(m_stDiff));

    time_t ltime;
    time( &ltime );
    *m_pStrLog << ON_DUTY_STR << ctime(&ltime);

    int nHeapOkay = TRUE;
    *m_pStrLog << CHECK_HEAP_STR << endl;
    _ASSERT(nHeapOkay = _CrtCheckMemory());
    if ( nHeapOkay == TRUE )
    {
      *m_pStrLog << HEAP_IS_OKAY_STR << endl;
    }
    *m_pStrLog << TAKE_SNAPSHOT_STR << endl;
    _CrtMemCheckpoint(&m_stFirst);
    *m_pStrLog << DUMP_SNAPSHOT_STR << endl;
    _CrtMemDumpStatistics(&m_stFirst);
    m_stLast = m_stFirst;
  }
}

bool AppWatchMan::DoRounds(const char* szComment, FLAGS flags)
{
  bool bErrorFound = false;

  if ( m_bOnDuty )
  {
    bool bPotentialLeak = false;
    int  nHeapOkay      = TRUE;

    time_t ltime;
    time( &ltime );
    *m_pStrLog << endl << DO_ROUNDS_STR << szComment << " " \
               << ctime(&ltime);

    // Check the heap memory integrity before anything
    if ( (flags & CHECK_HEAP) != 0 )
    {
      *m_pStrLog << CHECK_HEAP_STR << endl;
      _ASSERT(nHeapOkay = _CrtCheckMemory());
      if ( nHeapOkay == TRUE )
      {
        *m_pStrLog << HEAP_IS_OKAY_STR << endl;
      }
      else
      {
        bErrorFound = true;
      }
    }

    // TAKE_SNAPSHOT
    if ( (flags & TAKE_SNAPSHOT) != 0 )
    {
      // Move Last Reading to Previous
      m_stPrevious = m_stLast;

      // Take a Reading (Win32 C Run Time Library)
      *m_pStrLog << TAKE_SNAPSHOT_STR << endl;
      _CrtMemCheckpoint(&m_stLast);

      if ( (flags & DUMP_SNAPSHOT) != 0  )
      {
        *m_pStrLog << DUMP_SNAPSHOT_STR << endl;
        _CrtMemDumpStatistics(&m_stLast);
      }
    }

    // COMP_TO_PREV
    if ( (flags & COMP_TO_PREV) != 0 )
    {
      bPotentialLeak = 
        (_CrtMemDifference( &m_stDiff,
                            &m_stPrevious,
                            &m_stLast )== TRUE) ? true : false;
      if ( bPotentialLeak )
      {
        bErrorFound = true;
        *m_pStrLog << POTENTIAL_LEAK_STR << endl;
      }
      *m_pStrLog << COMP_TO_PREV_STR << endl;
      _CrtMemDumpStatistics(&m_stDiff);
    }

    // COMP_TO_START
    if ( (flags & COMP_TO_START) != 0 )
    {
      bPotentialLeak = 
        (_CrtMemDifference( &m_stDiff,
                            &m_stFirst,
                            &m_stLast )== TRUE) ? true : false;
      if ( bPotentialLeak )
      {
        bErrorFound = true;
        *m_pStrLog << POTENTIAL_LEAK_STR << endl;
      }
      *m_pStrLog << COMP_TO_START_STR << endl;
      _CrtMemDumpStatistics(&m_stDiff);
    }

    // LEAKS_FROM_PREV (only if there is a diff.)
    if ( (flags & LEAKS_FROM_PREV) != 0 )
    {
      bPotentialLeak = 
        (_CrtMemDifference( &m_stDiff,
                            &m_stPrevious,
                            &m_stLast )== TRUE) ? true : false;
      if ( bPotentialLeak )
      {
        bErrorFound = true;
        *m_pStrLog << POTENTIAL_LEAK_STR << endl;
        *m_pStrLog << LEAKS_FROM_PREV_STR << endl;
        _CrtMemDumpAllObjectsSince(&m_stPrevious);
      }
    }

    // LEAKS_FROM_START
    if ( (flags & LEAKS_FROM_START) != 0 )
    {
      bPotentialLeak = 
        (_CrtMemDifference( &m_stDiff,
                            &m_stFirst,
                            &m_stLast ) == TRUE) ? true : false;
      if ( bPotentialLeak )
      {
        bErrorFound = true;
        *m_pStrLog << POTENTIAL_LEAK_STR << endl;
        *m_pStrLog << LEAKS_FROM_START_STR << endl;
        _CrtMemDumpAllObjectsSince(&m_stFirst);
      }
      else
      {
        *m_pStrLog << NO_LEAKS_STR << " Since First Snapshot!" 
                   << endl;
      }
    }
  }
  return bErrorFound;
}

// end of AppWatchMan.cpp
— End of Listing —