Activity 12-2 - Dynamic Arrays


There is a close association between pointers and arrays. Recall from Lab 10, how array elements were accessed. In C++, an array variable is actually a pointer variable that points to the first indexed variable of the array. Array elements can be accessed using pointer notation as well as array notation. Recall program P10_1.cpp from Lab 10:

// P10_1.cpp - A program that uses an array of integers
#include <iostream>
using namespace std;
int main( )
{
   int numlist[8];
   int i;

   // Read 8 integers from the keyboard
   for (i = 0; i<8; i++ )
   {
             cout << "Enter value #" << i+1 << ": ";
             cin >> numlist[i];
    }
   // Display the numbers in a reverse order
   for (i = 8; i > 0; i-- )
  {
             cout << "Value #" << i << ": ";
             cout << numlist[i-1] << endl; //Pay attention to i-1!
   }

   return 0;
}

Now let's re-write the program and access the array numlist using pointer notation.

// P12_2.cpp - A program that uses an array of integers. Array elements accessed using pointer notation
#include <iostream>
using namespace std;
int main(void)
{
   int numlist[8];

   // Read 8 integers from the keyboard
   for (int i = 0; i<8; i++ )
   {
             cout << "Enter value #" << i+1 << ": ";
             cin >> numlist[i];
    }
   // Display the numbers in a reverse order
   for (int i = 8; i > 0; i-- )
  {
             cout << "Value #" << i << ": ";
             cout <<*( numlist + (i-1))<< endl; //Pay attention to i-1!
   }

   return 0;
}

In the above program, note how the array elements are accessed. The variable numlist is used as a pointer that points to the first element of the array.
 
Pointer variable Memory Address Contents of memory (Array elements)
numlist[0]
333000
*numlist[0] = 9
numlist[1]
333002
*numlist[1] = 7
numlist[2]
333004
*numlist[2] = 8
numlist[3]
333006
*numlist[3] = 7
numlist[4]
333008
*numlist[4] = 7
numlist[5]
333010
*numlist[5] = 9
numlist[6]
333012
*numlist[6] = 1
numlist[7]
333014
*numlist[7] = 6

One problem with the kinds of arrays we have used until now is that we must specify the size of the array when we write the program.   This may cause two different problems; 1) we may create an array much larger than needed, 2) we may create one that is smaller than what is needed.  In general, this problem is created because we don't know the size of the array until the program is run. This is where dynamic arrays are used. The new expression can be used to allocate an array on the freestore.Since array variables are pointer variables you can use the new operator to create dynamic variables that are arrays and treat these dynamic array variables as if they were ordinary arrays. Recall program P10_1b.cpp from lab 10. It is reproduced here below

// P10_1b.cpp - A program that uses a flexible size array of integers
#include <iostream>
using namespace std;
const int SIZE = 8; // Set the maximum size for the array

int main(void)
{
    int numlist[SIZE];

    // Read SIZE integers from the keyboard
    for (int i = 0; i<SIZE; i++ )
   {
       cout << "Enter value #" << i+1 << ": ";
       cin >> numlist[i];
    }
    // Display the numbers in a reverse order
    for (int i = SIZE; i > 0; i-- )
   {
       cout << "Value #" << i << ": ";
       cout << numlist[i-1] << endl; //Pay attention to i-1!
   }

   return 0;

}

Note that SIZE was defined as a const int. Now lets modify this program and re-write it creating the array dynamically.

// P12_2a.cpp. Illustrates dynamic arrays
#include <iostream>
using namespace std;

int main(void)
{
   int SIZE;
   cout<<"Enter the size of the array"<<endl;
   cin>>SIZE;

    int *numlist = new int[SIZE];

    // Read SIZE integers from the keyboard
    for (int i = 0; i<SIZE; i++ )
   {
       cout << "Enter value #" << i+1 << ": ";
       cin >> numlist[i];
    }
    // Display the numbers in a reverse order
    for (int i = SIZE; i > 0; i-- )
   {
       cout << "Value #" << i << ": ";
       cout << numlist[i-1] << endl; //Pay attention to i-1!
    }
   delete[] numlist;
   return 0;
}

Note how the array numlist has been declared dynamically using the new operator to meet the required size on the freestore. As new reserves memory on the freestore it is not automatically freed once the memory is no longer needed. In an efficient program, we may take as much memory as we need and free them when once we are done with them.  We need to use the delete operator to free the memory that is occupied from the freestore . Notice the empty square brackets along with the pointer variable numlist. This statement deletes the space on the occupied freestore by numlist and recycles it.

Display 12.5 in the textbook lists a program that uses dynamic arrays to sort a list of numbers entered at the keyboard.

A dynamic array can have a base type which is a class. You can use the base type class just as you would use a predefined data type integer or float.

Exercise 12.2
Define a class Student that has as its members the student_name and a student_ idnumber both of type string. Input from the keyboard the number of students in the database, then create a dynamic array of type Student and input the information for each student. Once you populate the database (stored all information), display the entire database. Remember to delete the dynamic array pointer before exiting the program.