home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / stock / mem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-12  |  4.8 KB  |  195 lines

  1. /***    mem.c - memory definitions
  2.  *
  3.  *    routines that layer C run-time library memory
  4.  *    routines to provide debugging assistance.
  5.  *
  6.  *    History
  7.  *        07-Mar-1990 bens    Initial version.
  8.  *        08-Mar-1990 bens    Added heap check code
  9.  *        16-Mar-1990 bens    MyAlloc should return NULL on failure!
  10.  */
  11. #ifdef CHECKASSERTS
  12.  
  13. #define INCL_WINWINDOWMGR
  14.  
  15. #include <os2.h>
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <memory.h>
  21.  
  22. #include "mem.h"
  23.  
  24. typedef ULONG MEMSIG;     // ms
  25. typedef MEMSIG *PMEMSIG; // pms
  26.  
  27. typedef struct mh_s {     // mh
  28.     MEMSIG        ms;         // Head signature
  29.     USHORT        cb;         // Size of user block
  30.     struct mh_s *   pmhNext;        // Next block
  31.     struct mh_s *   pmhPrev;        // Previous block
  32.     // char ach[?];            // User block; length is cb
  33.     // MEMSIG ms[?];            // Tail signature area
  34. } MEMHDR;
  35. typedef MEMHDR *PMEMHDR; // pmh
  36.  
  37. #define MEMSIG_HEAD    0x12345678L
  38. #define MEMSIG_TAIL    0x87654321L
  39. #define MEMSIG_BAD     0L
  40. #define TAIL_SIZE   2            // 8-byte tail
  41.  
  42. void FailAssert(char *sz);
  43.  
  44. char achBug[CCHMAXPATH];        // Buffer for formatting errors
  45. PMEMHDR pmhList=NULL;            // List of memory blocks
  46.  
  47.  
  48. /***    FailAssert - common exit for assertion failure
  49. *
  50. *    ENTRY    sz - message string
  51. *
  52. *    EXIT    issue message and exit
  53. */
  54. void FailAssert(char *sz)
  55. {
  56.     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, sz,
  57.     "Assertion Failure", 0, MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
  58.     DosExit(1,2);
  59. }
  60.  
  61.  
  62. void MyCheckHeap(char *pszFile,USHORT line)
  63. {
  64.     PMEMHDR pmh;
  65.  
  66.     for (pmh = pmhList; pmh != NULL; pmh = pmh->pmhNext)
  67.     MyAssert((char *)pmh+sizeof(MEMHDR),pszFile,line);
  68. }
  69.  
  70.  
  71. void MyAssert(void *pv,char *pszFile,USHORT line)
  72. {
  73.     USHORT  cb;
  74.     int     i;
  75.     PMEMHDR pmh;
  76.     PMEMSIG pms;
  77.  
  78.     pmh = (PMEMHDR)((char *)pv - sizeof(MEMHDR));
  79.     if (pmh > pv) {            // Pointer wrapped
  80.     sprintf(achBug,"%s:%d: panic: NULL pointer(?)",pszFile,line);
  81.     FailAssert(achBug);
  82.     }
  83.  
  84.     // Test head signature
  85.     if (pmh->ms != MEMSIG_HEAD) {
  86.     sprintf(achBug,"%s:%d: panic: memory header trashed",pszFile,line);
  87.     FailAssert(achBug);
  88.     } else {
  89.     // Test tail signatures
  90.     pms = (PMEMSIG)( (char *)pmh + sizeof(MEMHDR) + pmh->cb );
  91.     for (i=0; i<TAIL_SIZE; i++) {
  92.         if (*pms++ != MEMSIG_TAIL) {
  93.         sprintf(achBug,"%s:%d: panic: memory tail trashed",pszFile,line);
  94.         FailAssert(achBug);
  95.         }
  96.     }
  97.     }
  98.  
  99. }
  100.  
  101.  
  102. void MyFree(void *pv,char *pszFile,USHORT line)
  103. {
  104.     PMEMHDR pmh;
  105.  
  106.     MyAssert(pv,pszFile,line);
  107.  
  108.     pmh = (PMEMHDR)((char *)pv - sizeof(MEMHDR));
  109.  
  110.     // Make previous block point to next block
  111.     if (pmh->pmhPrev != NULL) {     // pmh is not at front of list
  112.     // before: a->p->?
  113.     pmh->pmhPrev->pmhNext = pmh->pmhNext;
  114.     // after:  a->?
  115.     }
  116.     else {                // pmh is at front of list
  117.     // before: list->p->?
  118.     pmhList = pmh->pmhNext;
  119.     // after: list->?
  120.     }
  121.  
  122.     // Make next block point to previous block
  123.     if (pmh->pmhNext != NULL) {     // pmh is not at end of list
  124.     // before: ?<-p<->a
  125.     pmh->pmhNext->pmhPrev = pmh->pmhPrev;
  126.     // after:  ?<-a
  127.     }
  128.  
  129.     // Obliterate signature
  130.     pmh->ms = MEMSIG_BAD;
  131.  
  132.     // Free memory
  133.     free((char *)pmh);
  134. }
  135.  
  136.  
  137. void *MyAlloc(USHORT cb,char *pszFile,USHORT line)
  138. {
  139.     USHORT    cbAlloc;
  140.     int     i;
  141.     char *    pch;
  142.     PMEMHDR    pmh;
  143.     PMEMSIG    pms;
  144.  
  145.     MyCheckHeap(pszFile,line);
  146.  
  147.     cbAlloc = cb+sizeof(MEMHDR)+sizeof(MEMSIG_TAIL)*TAIL_SIZE;
  148.     pmh = malloc(cbAlloc);
  149.     if (pmh != NULL) {
  150.     pmh->ms = MEMSIG_HEAD;        // Store head signature
  151.     pmh->cb = cb;            // Store size of user block
  152.  
  153.     // Add block to front of list (Easiest code!)
  154.     if (pmhList != NULL)        // List is not empty
  155.         pmhList->pmhPrev = pmh;    // Point old top block back at us
  156.     pmh->pmhNext = pmhList;     // Next element is old top block
  157.     pmh->pmhPrev = NULL;        // We are first, so no prev block
  158.     pmhList = pmh;            // Make ourselves first
  159.  
  160.     // Fill in tail signatures
  161.     pms = (PMEMSIG)( (char *)pmh + sizeof(MEMHDR) + pmh->cb );
  162.     for (i=0; i<TAIL_SIZE; i++)
  163.         *pms++ = MEMSIG_TAIL;
  164.     return ((char *)pmh + sizeof(MEMHDR));
  165.     }
  166.     else {
  167.     printf("panic: out of memory in MyAlloc\n");
  168.     printf("\n");
  169.     printf("Dump of heap (newest alloc to oldest)\n");
  170.     printf("\n");
  171.     printf("Size  Addr Content\n");
  172.     printf("----- ---- -------\n");
  173.     for (pmh = pmhList; pmh != NULL; pmh = pmh->pmhNext) {
  174.         pch = (char *)pmh + sizeof(MEMHDR);
  175.         printf("%5d %04x %s\n",pmh->cb,(USHORT)pch,pch);
  176.     }
  177.     return NULL;
  178.     }
  179. }
  180.  
  181.  
  182. char *MyStrDup(char *pch,char *pszFile,USHORT line)
  183. {
  184.     USHORT  cb;
  185.     char *  pchDst;
  186.  
  187.     cb = strlen(pch)+1;         // Count NUL terminator
  188.     pchDst = MyAlloc(cb,pszFile,line);    // Alloc new copy
  189.     if (pchDst != NULL) {        //  Success
  190.     memcpy(pchDst,pch,cb);        // Copy string
  191.     }
  192.     return pchDst;            // Return string copy
  193. }
  194. #endif
  195.