home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_02 / 8n02133a < prev    next >
Text File  |  1990-03-01  |  7KB  |  132 lines

  1. /*----------------------------------------------------------------------
  2.   membug.c
  3.   Demonstrate MSC malloc() large size problem
  4.  
  5.   Description
  6.  
  7.        membug.c demonstrates a problem that occurs when Microsoft C,
  8.        version 5.10 is used to allocate and free large blocks of
  9.        memory.
  10.  
  11.        If this program is compiled and run, you will find 
  12.        that the first list will have significantly more memory
  13.        allocated to it. The second list will only have 1 to 2
  14.        elements allocated to it, depending on your memory layout.
  15.  
  16.        The basic problem is that MSC never deallocates a DOS
  17.        allocated memory block, even if the memory call is about to
  18.        fail. Thus, the first list causes the MSC runtime to allocate
  19.        memory in 48K blocks. When the first list is freed, the
  20.        48K blocks remain. Then, when the second list is allocated,
  21.        there are only 2 blocks that DOS can carve the 60K blocks
  22.        from: the default memory segment and the last DOS memory block.
  23.        The default memory segment is 64K, so we should always get
  24.        an allocation from it. The last memory block can be expanded
  25.        by DOS to fit the 60K request if your memory layout will allow
  26.        it.
  27.  
  28.        Note that if you reverse the order of memory requests, both
  29.        will return the same number of memory blocks because the 48K
  30.        requests will fit in the 60K blocks.
  31.  
  32.   Compilation
  33.  
  34.        Compilation is under Microsoft C, verison 5.1 using the command:
  35.  
  36.                c1 /W3 /AL membug.c
  37.  
  38.   Execution
  39.  
  40.        Execution of the program should use the command line:
  41.  
  42.                membug > membug.out
  43. */
  44.  
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <dos.h>
  49.  
  50. /* Local definitions */
  51. /* ----------------- */
  52. #define FIRST_ALLOC_SIZE     48000
  53. #define SECOND_ALLOC_SIZE    60000
  54.  
  55. /* Memory allocation list structure */
  56. /* -------------------------------- */
  57. typedef struct mb                       /* Memory list node             */
  58.         {                               /* ---------------------------- */
  59.         struct mb *     mb_next ;       /* Pointer to next block    */
  60.         char            mb_data ;       /* Start of data area           */
  61.                                         /* Actual data area size is     */
  62.                                         /* determined by runtime        */
  63.                                         /* malloc() argument            */
  64.         } MEM_BLOCK ;
  65.  
  66. /* Pointer conversion macros */
  67. /* ------------------------- */
  68. #define FARPTR_SEG(a) ((int) (((unsigned long) (a)) >> 16))
  69. #define FARPTR_OFF(a) ((int) ((long) (a)))
  70. #define MAKE_FARPTR(seg,off) ((void far *) ((((long) (seg)) << 16) + (off)))
  71.  
  72. /* Function prototypes */
  73. /* ------------------- */
  74. void    main() ;
  75. void    DOS_Mem_Display(char *) ;
  76.  
  77. /*------------------------------------------------------------------------
  78.  
  79.   main
  80.   Entry point for MSC dynamic memory test
  81.  
  82.   Usage
  83.  
  84.      void
  85.      main()
  86.  
  87.   Parameters
  88.  
  89.      None
  90.  
  91.   Description
  92.  
  93.      main() is the entry point for the Microsoft C dynamic memory
  94.      test. The function allocates a list of FIRST_ALLOC_SIZE 
  95.      elements, frees the first list, allocates a second
  96.      list of SECOND_ALLOC_SIZE, and frees the second list. The
  97.      statistics printed out are the total bytes allocated by each
  98.      allocation and a dump of the DOS memory list after each
  99.      allocation/free.
  100.  
  101.   Notes
  102.  
  103.      None
  104. */
  105.  
  106. void
  107.  
  108.  
  109. main()
  110. {
  111. MEM_BLOCK * list ;
  112. MEM_BLOCK * p ;
  113. long    first_size ;
  114. long    second_size ;
  115.  
  116. /* Allocate list using first allocation size */
  117. /* ----------------------------------------- */
  118. list = NULL ;
  119. first_size = 0 ;
  120. while ((p = (MEM_BLOCK *) malloc(FIRST_ALLOC_SIZE)) != NULL)
  121.     {
  122.     p->mb_next = list ;
  123.     list = p ;
  124.     first_size += FIRST_ALLOC_SIZE ;
  125.     }
  126.  
  127. /* Print first allocation results */
  128. /* ------------------------------ */
  129. printf("***** First allocation - %ld *****\n\n", first_size) ;
  130. DOS_Mem_Display("After first allocation\n") ;
  131.  
  132. /* Free first