Listing 3

#include <stdio.h>
#include <stdlib.h>

main()
{
   void **alloc2da(size_t rows, size_t cols, size_t elemsize,
      size_t elptrsize);
   int rows = 0;
   int cols = 0;
   long **pl;
   double **pd;
   int i, j;

   while (rows < 1 || cols < 1) {
      printf("Enter number of rows and columns: ");
      scanf("%d %d", &rows, &cols);
   }

/* allocate a 2D array of rows x cols long ints */

   pl = alloc2da(rows, cols, sizeof(long), sizeof(long *));
   if (pl == NULL) {
      printf("Can't allocate array of longs\n");
      exit(1);
   }

   printf("\nArray pl\n");
   for (i = 0; i < rows; ++i) {
      printf("Row: %2d", i);
      for (j = 0; j < cols; ++j)
         printf(" %p", &pl[i][j]);
      putchar('\n');
   }

/* allocate a 2D array of cols x rows doubles */

   pd = alloc2da(cols, rows, sizeof(double), sizeof(double *));
   if (pd == NULL) {
       printf("Can't allocate array of doubles\n");
       exit(1);
   }

   printf("\nArray pd\n");
   for (i = 0; i < cols; ++i) {
       printf("Row: %2d", i);
       for (j = 0; j < rows; ++j)
          printf(" %p", &pd[i][j]);
       putchar('\n');
   }
}

/* not maximally portable for other than 2D arrays of char */

void **alloc2da(size_t rows, size_t cols, size_t elemsize,
   size_t elptrsize)
{
   void **aryadr;
   size_t i;

   aryadr = malloc(rows * elptrsize);
   if (aryadr == NULL)
      return NULL;

   for (i = 0; i < rows; ++i) {
      aryadr[i] = malloc(cols * elemsize);
      if (aryadr[i] == NULL)
         return NULL;
   }

   return aryadr;
}

Enter number of rows and columns: 3 4

Array pl
Row:  0  4AB2  4AB6  4ABA  4ABE
Row:  1  4AC4  4AC8  4ACC  4ADO
Row:  2  4AD6  4ADA  4ADE  4AE2

Array pd
Row:  0  4AF2  4AFA  4B02
Row:  1  4BOC  4B14  4B1C
Row:  2  4B26  4B2E  4B36
Row:  3  4B40  4B48  4B50