You are currently offline, waiting for your internet to reconnect

INFO: Dynamic Memory Allocation for Two-Dimensional Arrays

This article was previously published under Q104639
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
SUMMARY
The C language does not internally support dynamic memory allocation fortwo-dimensional arrays. Creating such a structure requires some programmingto set it up; however, once created the elements can be referred to by thefamiliar double bracket ([][]) notation. There is memory overhead involvedin creating the structure. This technique is platform-independent workingin the MS-DOS, Windows, Windows NT, and OS/2 operating systems.
MORE INFORMATION
For the compiler to generate code for two-dimensional array elementdereferencing, the number of columns of the array must be known at compiletime. Therefore, it is possible to dynamically allocate a two-dimensionalarray if pointer declaration includes the "width" of the array. Below is acode fragment that illustrates this:
char (*array)[columns];array = (char (*)[columns]) malloc(sizeof(char) * rows * columns);if (array == NULL){    printf("Not enough memory!\n");    return;}				
However, to give both dimensions of a two-dimensional array at run time thearray must be dynamically allocated. In this case, a dynamically allocatedtwo-dimensional array should be thought of as an array of one-dimensionalarrays. There is some memory overhead, however, which requires allocationof an array of array pointers that is not necessary for statically definedtwo-dimensional arrays. Despite the overhead, each element of the two-dimensional arrays can be referenced with the bracket notation just as fora statically defined two-dimensional array.

These are the steps for dynamically allocating a two-dimensional array:
  1. Declare a double dereferenced pointer of a desired type.
  2. Allocate the number of rows times the size of a pointer and assign the first dereference to the beginning of this allocation.
  3. Loop through the rows and allocate the number of columns times the size of the element.
The structure conceptually resembles the following:
   Array of                    Arrays of   Pointers                    Elements   ------     -------------------------                      -------   |    | -->|   |   |   |   |   |   |     . . . . . . .       |   |   ------     -------------------------                      -------   |    | -->|   |   |   |   |   |   |     . . . . . . .       |   |   ------     -------------------------                      -------   |    | -->|   |   |   |   |   |   |     . . . . . . .       |   |   ------     -------------------------                      -------   |    | -->|   |   |   |   |   |   |     . . . . . . .       |   |   ------     -------------------------                      -------         .         .         .         .         .    -------------------------                      -------   |    | -->|   |   |   |   |   |   |     . . . . . . .       |   |   ------     -------------------------                      -------   |    | -->|   |   |   |   |   |   |     . . . . . . .       |   |   ------     -------------------------                      -------				
Use _fmalloc() for MS-DOS and 16-Bit Windows to use the far/globalheap. Note for Windows: _fmalloc() is available to be used whencompiling with Microsoft C/C++ compiler versions 7.0, 8.0, and 8.0c.Do not use GlobalAlloc and GlobalLock because this technique may useup too many selectors for relatively small allocations.

Unlike a statically declared two-dimensional array, the rows are notcontiguous with one another. But because this is an array of arrays itis possible to have a total structure larger than 64K without usinghuge pointers. If either the number of rows or the size of the rows isgreater than 64K, then huge pointers are necessary.

Sample Code

/* Semi-pseudo code for a two-dimensional array of char's* Note that this sample uses the far heap and uses far pointers.* For 32-Bit Windows applications on Windows NT or Win32S or for* OS/2, use malloc() and remove the _far keywords.*/    char _far * _far * array;   unsigned int i;   unsigned int rows, columns;  /* let's keep it within 64k */    /*  Set the rows and columns to desired dimensions. */    rows    = 8;   columns = 12;   array = (char _far * _far *) _fmalloc(sizeof(char _far *) * rows);   if (array == NULL)   {       printf("Not enough memory\n");       return;   }   for (i = 0; i < rows; i++)   {       array[i] = (char _far *) _fmalloc(sizeof(char) * columns);       if (array[i] == NULL)       {           printf("Not enough memory\n");           /* handle error, _free() the previously allocated rows */            return;       }   }   /* to use the array: array[row][column] */    array[0][1] = 'x';   /* etc.   */ * To Free the memory used by the array***/    for (i = 0; i< rows; i++)       _ffree(array[i]);   _ffree(array);				
kbinf halloc
Properties

Article ID: 104639 - Last Review: 12/02/2003 14:12:18 - Revision: 2.0

  • Microsoft Visual C++ 1.0 Professional Edition
  • Microsoft Visual C++ 1.5 Professional Edition
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 2.1
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 4.1 Subscription
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • kbinfo kblangc KB104639
Feedback