Dynamically Allocating Memory for an Array

InPursuitYes, I know I haven’t written in a while. I’ve been busy. I decided to go back to college to learn the things I wanted to learn. I would get so far with C, then my eyes would glaze over. So, I’ve been taking 14 hours while working full time, to force myself to learn to code the things my mind typically avoids.

I’m finding that the course material is better for me than the tutorials I find online. One case in point is using malloc to dynamically allocate memory for arrays. This is something I wouldn’t have been able to do before. I’ve been taking C++ at school and it’s making C easier for me to understand. I’m taking the second semester of C++ in the spring, and a C class as well.

Enough of that, let’s create a dynamic array! I’ve taken someone else’s code, that I felt was incomplete, and rewritten it. This program runs fine on Linux. You may want to add #include <conio.h> to the include statements at the beginning if you are using a Microsoft OS.

// first we include the libraries
#include <stdio.h>
#include <stdlib.h>

// everything else, we'll do in main
int main() {
  // declare variables, including
  // array declared as int* array; a pointer
  // initially point it to NULL to avoid potential problems
  // programmers differ on whether the pointer should be type cast
  // a void pointer will return an error if you forget to include
  // the library but type casting makes the code compilable in C++
  int* array = NULL;

  // n will be a user-supplied number
  // i will be used as a counter in the for loop(s)
  int n, i;

  // Ask the user how many elements they want in the array
  printf("Enter the number of elements you want in the array: ");
  scanf("%d", &n);

  // this statement allocates memory for
  // n elements the size of an int
  array = (int*) malloc(n*sizeof(int));

  // check to see if the memory allocation failed
  // if it did, notify the user of the problem
  // and terminate the program with an error
  if(NULL == array)
  {
    puts("\nError allocating memory for array! Terminating!\n");
    return 1;
  }

  // everything's okay, so we'll ask the user to
  // enter a number for each element of the array
  for (i=0; i<n; i++) {
  printf("Enter number %d: ", i);
  scanf("%d", &array[i]);
  }

  // output the array one element at a time
  // then output its size for the user
  printf("\nThe Dynamic Array is: \n");
  for (i=0; i<n; i++) {
  printf("The value of %d is %d\n", i, array[i]);
  }
  printf("Size= %d\n", i);

  // when finished, free the memory that was allocated for the array
  free(array);

  // point the pointer to null
  // so you do not accidentally 
  // try to use it again with
  // unexpected results
  array = NULL;

  // return zero, exiting without errors
  return 0;
}

I thought it pretty strange that one example I saw didn’t show the user how to free the memory after the operation. Also, several didn’t bother setting the array pointer to point at NULL.

Memory is routinely freed once it is no longer in use by the program. If you want your program to run efficiently and cleanly, manually freeing memory that is no longer in use is more than just a good idea. The ability to directly manage memory like this is one of the big reasons to use a lower-level language like C or a mid-level language like C++. Assigning the pointer to NULL after freeing memory assures that you will get an error message if you accidentally try to use the pointer again to access the memory that has been freed.

Speaking of C++, I found the following example of doing the same thing in that language.

// i am not providing the full code here, just snippets

// start by declaring the pointer and initializing it to NULL
// C++ is a strongly typed language, so you must declare the 
// proper type for the array you want to use
int* a = NULL;
  
int n;           // declare the size variable

cin >> n;        // get the size from the user
a = new int[n];  // allocate memory for that number of ints
                 // note the comparative simplicity of the
                 // statement compared to the C statement
// increment through the elements
// put one more than the number of 
// that element in the element 
// will read 1 2 3 ... n when outputting 
for (int i=0; i<n; i++)
{
    a[i] = i+1;
}

// now iterate again, printing each array element
for(int i=0; i<n; i++
{
    cout << a[i] << endl;
}

// finished with the array, now free the memory
delete [] a;

// memory is free, now point the pointer a to NULL
// to prevent accessing the freed memory
a = NULL;

Memory that your program didn’t free will be freed when the program terminates but it’s best to free it manually where appropriate. Never free memory that wasn’t dynamically allocated – the results are unpredictable.

You must specify “[]” when deleting an array, but not for a single value. It isn’t possible
to delete only part of an array. As I mentioned before, setting the pointer to NULL isn’t strictly necessary, but it’s the best practice so that any further use of the pointer will produce an error. Some compilers will take care of that for you when you delete the
pointer but it’s best to do it anyway, just in case.

Advertisements

2 Replies to “Dynamically Allocating Memory for an Array”

  1. Perhaps I wasn’t clear enough about declaring a pointer for the array in C. Some programmers will declare something like:

    void *array;

    This allows the programmer to use it as any type of array, depending on the need. Since memory isn’t allocated at the time, it’s not necessary to declare a type in C. Type casting can result in supression of errors if the library is not included. However, it’s easier to compile the code in C++ if it becomes necessary, because C++ requires the correct type during initialization.

  2. By the way, to those who follow me on this blog, I’m setting up a self-hosted blog and will be making the transition away from this one over the holidays if all goes well. I’ll keep you posted and give you the new address when the time is right.

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