
#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  4AD0
Row:  2  4AD6  4ADA  4ADE  4AE2

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

