Dynamic Memory Management with malloc and free

Dynamic memory allocation is a technique in which programs determine as they are running where to store some information. You need dynamic allocation when the number of memory blocks you need, or how long you continue to need them, depends on the data you are working on.

For example, you may need a block to store a line read from an input file; since there is no limit to how long a line can be, you must allocate the storage dynamically and make it dynamically larger as you read more of the line.

When you use dynamic allocation, the allocation of a block of memory is an action that the program requests explicitly. You call a function when you want to allocate space, and specify the size with an argument. If you want to free the space, you do so by calling another function. You can do these things whenever you want, as often as you want.

The most general dynamic allocation facility is malloc. It allows you to allocate blocks of memory of any size at any time, make them bigger or smaller at any time, and free the blocks individually at any time (or never). The prototype for this function is in stdlib.h.


Function: void * malloc (size_t size);

This function returns a pointer to a newly allocated block size bytes long, or a null pointer if the block could not be allocated.

The contents of the block are undefined; you must initialize it yourself. Normally you would cast the value as a pointer to the kind of object that you want to store in the block. If no more space is available, malloc returns a null pointer. You should check the value of every call to malloc.


When you no longer need a block that you got with malloc, use the function free to make the block available to be allocated again. The prototype for this function is also in stdlib.h.

Function: void free (void *ptr)

The free function deallocates the block of storage pointed at by ptr.


Take a look at the following example:

 #include <stdio.h>
 #include <stdlib.h>

 int main()
 {
     int *ptr_int;

     ptr_int = (int *)malloc(sizeof(int));

     if (ptr_int == NULL)
     {
	printf("ERROR: Out of memory\n");
	return 1;
     }

     *ptr_int = 17;
     printf("%d\n", *ptr_int);

     free(ptr_int);

     return 0;
 }

In this example, the malloc statement asks for an amount of memory with the size of an integer (4 bytes). If there is not enough memory available, the malloc function will return NULL. If the request is granted a block of memory is allocated, and the address of the block is placed in the pointer variable.

The if statement then checks for the return value of NULL. If the return value equals NULL, then a message is printed and the programs exits.

The number seventeen is placed in the allocated memory and then printed out. Before the program ends the allocated memory is released.

Always use sizeof. Do not use malloc(4) for instance, to request 4 bytes for an integer. This will make your code more portable.


Remember that when allocating space for a string, the argument to malloc must be one plus the length of the string. This is because a string is terminated with a null character that does not count in the "length" of the string but does need space.
char *ptr;
int length = strlen("hello");
...
ptr = (char *) malloc (length + 1);


Here is an example that uses malloc with structures.

 #include <stdio.h>
 #include <stdlib.h>

 struct rec
 {
     int i;
     float PI;
     char c;
 };

 int main()
 {
    struct rec *ptr_one;
    ptr_one =(struct rec *) malloc (sizeof(struct rec));

    ptr_one->i  = 11;        /* same as (*ptr_struct).i = 11;      */ 
    ptr_one->PI = 3.1415;    /* same as (*ptr_struct).PI = 3.1415; */ 
    ptr_one->c  = 'A';       /* same as (*ptr_struct).c = 'A';     */ 

    printf("First value:  %d\n", ptr_one->i);
    printf("Second value: %f\n", ptr_one->PI);
    printf("Third value:  %c\n", ptr_one->c);

    free(ptr_one);

    return 0;
 }