[comp.lang.c++] new on two dimension array

uucigj@gandalf.sbc.com (Gregg Jensen (5-3531)) (10/17/90)

Novice question: how do you use new to allocate space for a two 
dimension array?

char **matrix = new ??????;

      Gregg Jensen
---------------------------------------------------------------------- 
 These opinions are my own and do not necessarily reflect my companies.
      Southwestern Bell Telephone
---------------------------------------------------------------------- 

pena@fuug.fi (Olli-Matti Penttinen) (10/24/90)

In article <1990Oct17.153438.12299@swbatl.sbc.com> uucigj@gandalf.sbc.com (Gregg Jensen (5-3531)) writes:


   >Novice question: how do you use new to allocate space for a two 
   >dimension array?

   >char **matrix = new ??????;


It's tempting to assume that

	char **matrix = new char[XMAX][YMAX];

would do the trick. However, the real problem lies elsewhere. When you
use a real multidimensional array, you only need room for the actual
elements, since the compiler knows how the calculate the offset of any
element at run time.  With dynamic arrays, it's a different thing: you
either 

	(a) explicitly calculate offsets

		char *matrix = new char[XMAX * YMAX];
		...
		matrix[i * YMAX + j] = ...;

or

	(b) in addition to the actual data, allocate an extra vector
	    of XMAX pointers (in this case char *) and initialize them
	    to point at elements 0, YMAX, 2 * YMAX, ... , (XMAX -1) * YMAX,
            respectively:

		char *data = new char[XMAX * YMAX];
		char *ptrs = new (char(*[XMAX]));
		for (int i = 0; i < XMAX; i++)
		    matrix[i] = data + i * YMAX;
		...
		matrix[i][j] = ...;

This works because by definition a[i][j] is actually *(*(a + i)+j).
Note, however that this seemless integration of dynamic
multi-dimensional arrays doesn't necessarily work for class objects,
whose [], *, &, etc. operators have different semantics from their
mundane counterparts. Note also that this approach is readily
extensible to 3, 4, ... dimensional cases, because every 3-D array can
be considered a 1-D array whose elements happen to be 2-D arrays (or
1-D arrays of 1-D arrays, for that matter) ad infinitum.

To make life easier, I wrote a couple of years ago a fairly portable
K&R C function, that only uses malloc() once to allocate and
initialize an arbitrary dimensioned array of any type. It is less than
100 lines of code, I think.  If anyone is interested, let me know.

I hope this helps,

==pena
--
Olli-Matti Penttinen <pena@innopoli.fi> | "When in doubt, use brute force." |
Brainware Oy                            |   --Ken Thompson                  |
Tekniikantie 17                         +-----------------------------------+
02150  ESPOO, Finland        Tel. +358 0 4375 320        Fax. +358 0 4553 117
--
Olli-Matti Penttinen <pena@innopoli.fi> | "When in doubt, use brute force." |
Brainware Oy                            |   ==Ken Thompson                  |
Tekniikantie 17                         +-----------------------------------+
02150  ESPOO, Finland        Tel. +358 0 4375 320        Fax. +358 0 4553 117

gregs@hpmtlx.HP.COM ($Greg_Stander) (10/26/90)

> Novice question: how do you use new to allocate space for a two
> dimension array?
> 
> char **matrix = new ??????;

Of course if dimensions are constants, this works and is usually easier.

#include <stream.h>
#include <stdio.h>

const int XMAX =   3;
const int YMAX =  20;
typedef char array_type[XMAX][YMAX];

main()
{
  array_type &myarray = *(array_type *)new char[XMAX * YMAX];

  // Init to some values
  for(int row=0; row<XMAX; row++)
    for(int col=0; col<YMAX; col++)
      myarray[row][col] = 'z';
  for(row=0; row<XMAX; row++)
    sprintf(myarray[row], "This is row %d", row);

  // Show as array
  for(row=0; row<XMAX; row++)
      cout << "myarray[" << row << "] = " << myarray[row] << "\n";
  
  // Show as individiual characters
  char *show = (char *)myarray;
  for(int index = 0; index<XMAX*YMAX; index++)
    cout << show[index] << (((index+1)%YMAX)?"":"\n");
}

Greg Stander