Arrays and Pointers 4: Arrays of any type

We can store any type of object we like in an array. We've seen ints, doubles, strings, etc. already. We could choose something more exotic, like ofstreams, even! For example, imagine a situation where we'd like a program that reads a list of file names from the user, creates those files, and then takes a sentence he types and writes it to each of those files. Can we do this? Well, let's try the following strategy:


  // Get number of files, call it N
  int N;
  cout << "Enter number of files: ";
  cin >> N;

  // Create an array of N ofstreams
  ofstream *FILE = new ofstream[N];
Now we have a problem, FILE points to M objects of type ofstream, but how do we tell each ofstream object what file they should point to? I mean usually we tell the object what file it should point to at the same time it is created, as in:
ofstream OUT("temp.txt");
When we create arrays of objects using new, those objects are uninitialized, so we have to go through and initialize each one individually. In this case, that means opening a file for each ofstream object. To do this, we need to use .open() to attach a stream to a file. For example, we can create OUT as above in this way:

ofstream OUT;
OUT.open("temp.txt");
In the case of our array, we can read in names and initialize this way:

cout << "Please enter " << N << " filenames: ";
for( int j = 0; j < N; j++ ) {
  string s;
  cin >> s;
  FILE[j].open(s.c_str());
}
Having done this, we can write whatever we want to all the files, like this:

for(int k = 0; k < N; k++)
  FILE[k] << "Hello file number " << k << "!!!" << endl;    
You can take a look at this complete program that writes a sentence to a whole list of files.

Multi-dimensional Arrays

Since we can have arrays of any type of object, why not an array of arrays? For example, suppose we have a class of 10 students, each with 10 homework grades, and the grade info is stored in a file grades.txt. I might want to read in the data and store it, so that I can then answer questions for the user - questions like how did student 6 do on homework 3?

Clearly, I'd like an array of 10 objects, each object representing all the homework grades for a given student. But what type of object can I use to store the 10 homework grades that correspond to a given student? An array of 10 ints, of course! So, each object in my array of students is itself an array of ints, i.e. each object is an int*. Remember, we create an array of 10 objects of type T like this:
T* array = new T[10]
So, if the type of object that gets stored in the array is int*, we create our array like this:
int** array = new int*[10];
Now, having done that, we have an array full of uninitialized pointers, in otherwords we have an array of pointers that don't yet point to anything! Thus, for each of these 10 pointers we must allocate an array for them to point to! Remember, array[i] is an object of type int*. So wherever you see array[i] just think of it as being a normal old pointer:

int** array = new int*[10];
for(int i = 0; i < 10; i++)
  array[i] = new int[10];
What gets created and how you index elements in it are depicted in this diagram:

This is how you can create "multi-dimensional" arrays in C++. You just have arrays of arrays! Okay, now let's read the grade information and store it in our 2-dimensional array:


ifstream IN("grades.txt");
for(int s = 0; s < 10; s++)
  for(int g = 0; g < 10; g++)
    IN >> array[s][g];
With this, I can get the grade for student stu on homework assignment hwa as array[stu][hwa]. This program is a simple one that reads the grade info and allows the user to ask questions about grades. This version makes nice use of functions, and gives you an idea of how we pass multi-dimensional arrays around for this sort of thing. Here are three extensions of the functionality of this program you might like to consider:

Destroying Multidimensional Arrays

As we've mentioned before, arrays allocated with new live on until the end of your program, or until deleted with the delete [] command. With mutli-dimensional arrays, you have to remember to delete each array you created. That means, if we refer back to the grades problem from above, that all of the arrays pointed to by the elements of the array grade must be deleted before we can delete the array grade itself.

  for(int k = 0; k < 10; k++)
    delete [] grade[k];
  delete [] grade;

Problems

  1. Picking random teams. The file names.txt contains a list of names (the number of names is given on the first line of the file). Read those names in, and get from the user a number of teams to be made from those names. The number of teams must evenly divide the number of names. The program should randomly assign names to teams, and display the result. Here is a sample run of the program.
    ~/$ ./ex1
    There are 24 people.
    How many teams would you like? (make it evenly divide n) 3
    Team 0: Mike Dan Chris Joni Christy Seung-Geol Cathy Susan
    Team 1: Gavin Nate Paul Adina Jeff Carl Karen Eric
    Team 2: Phong Betty Madeline Marianne Don Shirley Tim Steve
  2. tic-tac-toe