A Little C Primer/C Dynamic Memory Allocation & Deallocation

From Wikibooks, open books for an open world
Jump to navigation Jump to search

For simple programs, it is OK to just declare an array of a given size:

  char buffer[1024]

In more sophisticated programs, this leads to trouble. There may be no way of knowing how big an array needs to be for the specific task the program is performing, and so allocating an array in a fixed size will either result in wasted memory or in not having enough to do the job.

The answer to this problem is to have the program allocate the memory at runtime, and that's what the "malloc()" library function does. For example, let's use "malloc()" to allocate an array of "char":

   /*malloc.c */

   #include <stdio.h>
   #include <stdlib.h>                    /*For "malloc", "exit" functions. */

   int main()
   {
     char *p;                             /*Pointer to array. */
     unsigned count;                      /*Size of array. */
   
     puts( "Size of array?" );
     scanf( "%d", &count );                /*Get size in bytes. */
     p = malloc( (size_t)count );         /*Allocate array. */
     if( p == NULL )                      /*Check for failure. */
     {
       puts( "Can't allocate memory!" );
       exit( 0 );
     }
     puts( "Allocated array!" );
     free( p );                           /*Release memory. */
     return 0;
   }

The header file "stdlib.h" must be included, and a pointer to the memory block to be allocated must be declared. The "malloc()" function sets the pointer to the allocated memory block with:

   p = malloc( (size_t)count );

The count is in bytes and it is "cast" to the type of "size_t", which is defined in "stdio.h". The pointer returned by "malloc()" is assigned to the variable "p", which is of type "char *". In ANSI C, "malloc()" returns a pointer of type "void *", which can be assigned to any other pointer type without a cast.

If the "malloc()" fails because it can't allocate the memory, it returns the value NULL (as defined in "stdio.h").

It is simple to allocate other data types:

   int *buf;
   ...
   buf = malloc( (size_t)sizeof( int ) );

The "sizeof()" function is used to determine the number of bytes in the "int" data type.

When the programs finished using the memory block, it get rids of it using the "free" function:

   free( p );

C also contains two other memory-allocation functions closely related to "malloc()": the "calloc()" function, which performs the same function as "malloc()" but allows the block allocated to be specified in terms of number of elements:

   void *calloc( size_t <number_elements>, size_t <sizeof_element_type> );

—and the "realloc()" function, which reallocates the size of an array

that's already been allocated:

   void *realloc( void *<block_pointer>, size_t <size_in_bytes> );