From: almeida@ame.gsfc.nasa.gov (aswin m. almeida)
Subject:  allocs, multidim arrays, and FAQ
Keywords: allocs, multidim arrays, and FAQ
Organization: NASA Goddard
Date: Thu, 31 Dec 1992 17:03:07 GMT

Recently I attempted to create a small fragment of C
using the FAQ in the newsgroup.  Here is the fragment
from:

1) The Newsgroup

2.10:	How can I dynamically allocate a multidimensional array?

A:	It is usually best to allocate an array of pointers, and then
	initialize each pointer to a dynamically-allocated "row."  The
	resulting "ragged" array can save space, although it is not
	necessarily contiguous in memory as a real array would be.  Here
	is a two-dimensional example:

		int **array = (int **)malloc(nrows * sizeof(int *));
		for(i = 0; i < nrows; i++)
			array[i] = (int *)malloc(ncolumns * sizeof(int));

	(In "real" code, of course, malloc would be declared correctly,
	and each return value checked.)

	You can keep the array's contents contiguous, while making later
	reallocation of individual rows difficult, with a bit of
	explicit pointer arithmetic:

		int **array = (int **)malloc(nrows * sizeof(int *));
		array[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
		for(i = 1; i < nrows; i++)
			array[i] = array[0] + i * ncolumns;

	In either case, the elements of the dynamic array can be
	accessed with normal-looking array subscripts: array[i][j].

(My goal is to make an array accessible as array[i][j] on the fly)

2) The Program I wrote (I am new to C programming, don't laugh <: )
   (Implements the code above).

#include <stdio.h>

main ()
{

int i,j;

int nrows, ncolumns;

ncolumns = 10;

printf ("Enter array index: \n");
scanf ("%d", &nrows);


int **array = (int **) malloc (nrows * sizeof(int *));
for (i=0; i < nrows; i++)
  array[i] = (int *) malloc (ncolumns * sizeof(int *));

printf ("Reading array values, and printing\n");
for (i=0; i<10; i++)
  for (j=0; j<nrows; j++)
  {
    printf("%d x %d = %d\n",i,j,i*j);
    array[i][j] = i*j;
    printf("%d,%d = %d\n",i,j,array[i][j]);

  }

}

3) The program above is supposed to create a 2-dimensional array
   with one dimension already specified, one dimension user specified,
   and then it creates a multiplication table (pretty simple).
   Here are the compile errors I received:

accom: Error: malloctest.c, line 16: syntax error
       int **array = (int **) malloc (nrows * sizeof(int *));
       --^
accom: Error: malloctest.c, line 18: array undefined
         array[i] = (int *) malloc (ncolumns * sizeof(int *));
       ---------^
accom: Error: malloctest.c, line 18: illegal indirection
         array[i] = (int *) malloc (ncolumns * sizeof(int *));
       ---------^
accom: Error: malloctest.c, line 18: illegal combination of pointer and integer, op =
         array[i] = (int *) malloc (ncolumns * sizeof(int *));
       ------------------------------------------------------^
accom: Error: malloctest.c, line 18: types :   int  versus   pointer to int
         array[i] = (int *) malloc (ncolumns * sizeof(int *));
       ------------------------------------------------------^
accom: Error: malloctest.c, line 25: illegal indirection
           array[i][j] = i*j;
       -----------^
accom: Error: malloctest.c, line 25: illegal indirection
           array[i][j] = i*j;
       --------------^
accom: Error: malloctest.c, line 26: illegal indirection
           printf("%d,%d = %d\n",i,j,array[i][j]);
       -------------------------------------^
accom: Error: malloctest.c, line 26: illegal indirection
           printf("%d,%d = %d\n",i,j,array[i][j]);
       ----------------------------------------^

My apologies about the length of the problem, but I wished to make
the problem well stated so I can possibly get a good answer.
Where is the error, the FAQ code, or my code or something that
is machine dependent?  (Im using UNIX off of an SGI).

Email replies to almeida@ame.gsfc.nasa.gov, or post them here,
Im sure that some of us could use a little more elaboration
on use of the multidim arrays and allocation on the fly.

Thanks!

A. Almeida
Newsgroups: comp.lang.c