KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q59087: Determining Size of Memory Block Referenced by a Pointer

Article: Q59087
Product(s): See article
Version(s): 5.00   | 5.10
Operating System(s): MS-DOS | OS/2
Keyword(s): ENDUSER | s_quickc s_quickasm | mspl13_c
Last Modified: 15-MAR-1990

Question:

Is there a function in the Microsoft C run-time library that returns
the amount of memory that has been allocated to a pointer by malloc()?
If not, is there a way I can write my own?

Response:

There is no C run-time library function that explicitly returns the
amount of memory that has been allocated to a pointer by malloc().
However, it is possible to retrieve this information indirectly
through the Microsoft C run-time library function _heapwalk(). The
_heapwalk() function returns a heap information structure of the
following form:

   struct _heapinfo {
       int far * _pentry;
       size_t _size;
       int _useflag;
   } _HEAPINFO;

The information returned in this structure can be accessed directly or
used in writing a function that gives the size information you want.
The following is sample code:

#include <stddef.h>
#include <malloc.h>

size_t msize(void * pointer, int * error)
{
   struct _heapinfo info; /* Heap info structure */
   int   heap_status;     /* Heap status */
   size_t  ret_val;       /* msize() return value */

   info._pentry = NULL;   /* Initialize heap info structure */

   do {
      heap_status = _heapwalk(&info); /* Step through heap until */
   } while ((pointer != info._pentry) /* desired entry is found  */
     && (heap_status == _HEAPOK));   /* or a heap error occurs. */

   if(heap_status == _HEAPOK)
      if(info._useflag != _FREEENTRY)
         ret_val = info._size;          /* no errors */
      else {
         ret_val = -1;                  /* entry has been freed */
         *error = _FREEENTRY;
      }
   else {
      ret_val = -1;     /* a heap error occurred */
      *error = heap_status;
   }
   return(ret_val);
}

Note: The msize() function takes as a parameter a pointer pointing to
the base memory that was allocated. For msize() to work correctly,
this pointer MUST point to the base of the allocated block, and not
anywhere within that block.

The msize() function returns the size of the allocated block or -1 if
an error occurs. If -1 is returned, an error code is returned through
the error parameter. The error parameter will be one of the following
manifest constants:

   _FREENTRY      _HEAPEMPTY      _HEAPBADPTR
   _HEAPBADBEGIN  _HEAPBADNODE    _HEAPEND

These error codes are actually generated by the Microsoft run-time
library function _heapwalk(). Refer to your Microsoft C Compiler's
documentation on _heapwalk() for more information on the meaning of
these error codes.

Following is a sample program that uses of the msize() function to
find the amount of memory allocated to a pointer. This function is
designed to work in any memory model:

#include <stdio.h>
#include <malloc.h>

size_t msize(void *, int *);

void main (void)
{
   char * p;
   int    error;
   size_t size;

   p = (char *)malloc(sizeof(char) * 11)
   if(p = NULL) {
      printf("Memory allocation error\n");
      return;
   }

   size = msize(p,&error);
   if(size == -1)
      printf("An msize error has occurred\n");
   else
      printf("Size = %u\n", size);
}

Note: The malloc() function allocates 11 bytes of memory for use by
the pointer p. Surprisingly, msize() returns 12 as the size of the
allocated block. Actually, this is an expected result. Malloc() always
allocates even-byte amounts as a result of PC architecture.
Consequently, msize()'s return value always is an even amount.

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.