Dynamic Memory Allocation (Ch.26)

So far we have had to declare arrays to hold the largest amount of data that we expect to use.  This can be quite wasteful.

The computer has a large block of memory called the "heap".  So far we haven't used it in our programming.  Note that in the 20 Feb lecture we had a program to compute three difference statistical measures in one function.  But in computing the median it was necessary to sort the array, modifying it in the calling routine.  That is why the program generated a warning before doing that.

The program also allocated the array int x[10000]; — rather on the large side if we only needed to do 100.  While the program is executing, it can allocate memory from the heap to use as an array.

Our text discusses the malloc function, which takes as its one parameter the number of bytes required.  It also returns a value of type void* — meaning that you always have to cast it to the type of pointer we require.  In addition there is the calloc function which takes two parameters, the number of cells in the array and the size of one cell.  While malloc will just allocate the space and return a pointer to it, calloc will allocate the space, clear it (fill it with zeroes), and return a pointer to it.

Once you are finished with the space, you need to return it to the heap, which is done by the free function.  Failure to do this is referred to as a "memory link":  heap space has been allocated and then remains unavailable even after the function doing the allocation exits.  It is, however, critical that the parameter passed to free either be NULL or the pointer to space allocated earlier.  Failure to insure that has the potential of doing significant damage to your computer.

From the Linux man page for malloc and similar functions:

       void *malloc(size_t size);
       void free(void *ptr);
       void *calloc(size_t nmemb, size_t size);
Here is a small demonstration of using malloc:
demoMalloc.txt   demoMalloc.c   demoMalloc.exe

A few lines from this program:

   printf("How many cells?  ");
   scanf("%d", &num);
   ptr = (int*) malloc (num * sizeof *ptr);
//                            i.e., size of ptr[0]

Here is a small demonstration of using calloc:
demoCalloc.txt   demoCalloc.c   demoCalloc.exe

A few lines from this program:

   printf("How many cells?  ");
   scanf("%d", &num);
   ptr = (int*) calloc (num, sizeof *ptr);
//                           i.e., size of ptr[0]

Given these tools, we now can change our StatisticsDemo program from the 20 Feb lecture.  The initial array is declared based on user input, and can remain unaltered after the call to the doStats() function.  In that code we can allocate a scratch array, copy the parameter array into that, and sort the scratch array.  We need to remember to free the space afterwards.

StatisticsDemo2.txt   StatisticsDemo2.c   StatisticsDemo2.exe

The "dialog.c" program was originally covered 3 February to exercise gets(), strcpy() and strcat().  It now can be modified to be safe through use of dynamic memory allocation.  The space allocation is always for the strlen(buffer) plus one additional byte for the '\0' at the end.  Second parameter to calloc() is "sizeof *front" — the size of front[0], matched to the individual pointers.

Text is accepted into a very large buffer, and then the component fields are dynamically allocated in a "just in time" fashion. By the format being generted, the completed line will require sufficient space for the three lines read in plus four characters (for the two occurrences of ", "), plus the trailing null.
DynamicDialog.txt   DynamicDialog.c   DynamicDialog.exe

Drill:  question from the sample Exam 2 — ExamQuest.pdf
ExamQuest.txt   ExamQuest.c   ExamQuest.exe