Borland Online And The Cobb Group Present:


October, 1995 - Vol. 2 No. 10


Listing B: MEMTEST.CPP
#include <iostream.h>
#include <stdio.h>
#include <classlib\assoc.h>
#include <classlib\dict.h>
typedef unsigned char guardType;
typedef size_t blockSizeType;
typedef unsigned long int idNumberType;
enum dynamicOperation{NewObject, NewArray, 
	              DelObject, DelArray};
struct AllocDeallocRecord
{
  idNumberType idNumber;
  blockSizeType blockSize;
  dynamicOperation operation;
  AllocDeallocRecord(FILE* file)
  {
       fread(&idNumber, sizeof(idNumberType), 
            1, file);
       fread(&blockSize, sizeof(blockSizeType), 
            1, file);
       fread(&operation, sizeof(dynamicOperation), 
            1, file);
            }
};

unsigned HashValue(const idNumberType& rec)
{ return (unsigned)rec; }

typedef TDIAssociation<idNumberType, 
          AllocDeallocRecord> AllocDeallocAssoc;

void displayData(AllocDeallocAssoc& temp, void*)
{
  cout << "  Allocation #" 
    << temp.Value()->idNumber << endl;
  cout << "  Size - " 
    << temp.Value()->blockSize << endl;
  switch(temp.Value()->operation)
  {
       case NewObject:
            cout << "  Undeleted object" << endl;
            break;
       case NewArray:
            cout << "  Undeleted array" << endl;
            break;
       case DelObject:
            cout << "  Deleting unknown object" 
              << endl;
            break;
       case DelArray:
            cout << "  Deleting unknown array" 
              << endl;
            break;
       default:
            cout << "  Corruption error" << endl;
  }
}

int main()
{
  FILE * LogFile = fopen("memtest.log", "rb");

  long int allocCount = 0;
  long int allocTotal = 0;

  TDictionaryAsHashTable<AllocDeallocAssoc>
       MemDictionary;
  AllocDeallocRecord * newRec = 
    new AllocDeallocRecord(LogFile);
  while(!(LogFile->flags & _F_EOF))
  {
    AllocDeallocAssoc temp(newRec->idNumber, 
                           newRec);
    AllocDeallocAssoc * result =
      MemDictionary.Find(temp);

    if(result != 0)
    { // There's already an item with this id
      if((result->Value()->operation == 
          NewObject) &&
         (newRec->operation == DelArray))
      { cout << "Calling delete with array - id#" 
             << newRec->idNumber << endl;
      }
      else if((result->Value()->operation == 
               NewArray) &&
              (newRec->operation == DelObject))
      { cout 
         << "Calling delete[] with object - id#" 
         << newRec->idNumber << endl;
      }
      MemDictionary.Detach(*result);
    }
    else
    { // New allocation
      if((newRec->operation == NewObject) ||
         (newRec->operation == NewArray))
      { MemDictionary.Add(temp);
        ++allocCount;
        allocTotal += newRec->blockSize;
      }
      else
      { cout << "Deallocating id#" 
             << newRec->idNumber 
             << " twice" << endl;
        delete newRec;
      }
    }

    newRec = new AllocDeallocRecord(LogFile);
  }
  delete newRec;

  int errorCount = 
      MemDictionary.GetItemsInContainer();
  if(errorCount)
  { cout << errorCount 
         << " allocation errors!!" << endl;
     MemDictionary.ForEach(displayData, 
                           (void*)0);
  }

  cout << endl << "Total allocations - " 
       << allocCount << endl;
  cout << "Average allocation size - " 
       << allocTotal / allocCount << endl;

  fclose(LogFile);
  return 0;
}

Return to "Debugging dynamic memory allocations in C"


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.