Dynamic Storage Allocation

The malloc() function provides dynamically-allocated storage.

The malloc() function sets aside a contiguous chunk of bytes of memory and returns the address of this chunk to be stored in a pointer.

The calloc() function sets aside a block of memory in the same fashion as malloc(), but it also zero-initializes the memory, meaning that the allocated memory is filled with 0-bits. The calloc() function also takes two arguments, whereas malloc() takes only one. The calloc() function allocates the number of bytes produced by the product of the two arguments it receives.

#include "stdafx.h"
#include <stdlib.h>

int main()
{
 //allocate 1 int's worth of memory
 int *i = (int *)malloc(sizeof(int));
 //allocate 5 double variable's worth of memory
 double *dArray = (double *)malloc(sizeof(double) * 5);

 //let's use calloc()
 char *szText = (char *)calloc(64, sizeof(char));
 int *i2 = (int *)calloc(1, sizeof(int));

 //will display 'garbage' value
 printf("Allocated with malloc(), *i = %d\n", *i);
 //will display 0
 printf("Allocated with calloc(), *i2 = %d\n", *i2);

 return 0;
}

Allocated memory storage is on the heap. Traditionally, the heap started at the low address of the process and grew upwards, whereas the stack started at a high address and grew downwards. Occasionally, a stack-heap collision would occur, where the stack or the heap grew overwrote one or the other.  As memory on modern OSes is pageable virtual memory, this is no longer a concern. At this point, even the idea of the stack growing downward and the head growing upward is conceptual rather than literal.

If the allocated memory function asks for more bytes than are available on the heap, the malloc() or calloc() function returns a NULL pointer. So, by checking the pointer with NULL, we can ensure that the memory was allocated.

#include "stdafx.h"
#include <stdlib.h>

int main()
{
 int *iPtrArray = (int*)malloc(10 * sizeof(int));

 if (iPtrArray != NULL) {
 printf("Memory allocated.\n");
 }

 return 0;
}

When allocated memory has been used and is no longer needed, we can return it to the heap with the free() function. Memory that has been allocated dynamically should be free, otherwise we will end up with memory leaks.

Now, when a process ends, all of the memory is reclaimed by the system . Therefore, it is not necessarily a big deal if we do not call free() in the small programs we have been writing. However, it’s best to maintain the ironclad habit of free-ing all memory that has been dynamically allocated.

 #include "stdafx.h"
#include <stdlib.h>

int main()
{
 double *dPtrArray = (double *)malloc(sizeof(double) * 5);

 if (dPtrArray != NULL) {
 printf("Memory allocated!\n");
 }

 //free the memory
 free(dPtrArray);
 dPtrArray = NULL;

 return 0;
}

After calling free on a pointer, we should consider the pointer to have an undefined value. Setting the value of the pointer to NULL explicitly is a good practice. A dangling pointer can result if we try to access deallocated memory via a pointer.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s