2D arrays and pointers in ANSI C. (source)
Christos S. Zoulas
christos at batcomputer.tn.cornell.edu
Sun Dec 2 23:57:13 AEST 1990
In article <11616.2757eaf1 at ecs.umass.edu> lim at ecs.umass.edu writes:
>Hi,
>
>I'd appreciate any answers you may have to the following problem.
> It's about 2D arrays and pointers in ANSI C.
> ...
>I'm aware that it's possible to use just pointers (*) to access the array, but
>have had no luck trying to use something like matrix[i][j] in the test_matrix
>function. Is it possible to use matrix[i][j] at all? I've had no problem using
>matrix[i] for a *matrix argument (1D array).
I think the following piece of code will solve your problem:
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: README Makefile arrayn.c bigtest.c smalltest.c
# Wrapped by christos at guillemin on Sun Dec 2 07:52:19 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(467 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X#
X# README Fri Sep 8 02:12:57 EDT 1989
X#
XThis a a dynamic memory allocator for multi-dimensional arrays.
XIt computes the size of the array, (size of data + size of pointers).
XThen it allocates the array using malloc, and threads the pointers
Xto form a multi-dimensional array.
XThe source is in arrayn.c, and with it there are 2 test programs
Xsmalltest.c and bigtest.c
X
X
XPlease send comments, bugfixes etc. to
X
Xchristos at tesla.ee.cornell.edu or
Xchristos at crnlee.bitnet
END_OF_FILE
if test 467 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(320 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Makefile for arrayn
X#
XSHELL = /bin/sh
X#CFLAGS = -g -DDEBUG
XCFLAGS = -O
X
Xall : smalltest bigtest
X @echo "All done"
X
Xsmalltest : arrayn.o smalltest.o
X cc ${CFLAGS} arrayn.o smalltest.o -o smalltest
X
Xbigtest : arrayn.o bigtest.o
X cc ${CFLAGS} arrayn.o bigtest.o -o bigtest
X
Xarrayn.o : arrayn.c
X
Xclean :
X rm -f ${OBJ}
END_OF_FILE
if test 320 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'arrayn.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'arrayn.c'\"
else
echo shar: Extracting \"'arrayn.c'\" \(4107 characters\)
sed "s/^X//" >'arrayn.c' <<'END_OF_FILE'
X/* $Header: /home/hyperion/mu/christos/src/mine/lib/arrayn/RCS/arrayn.c,v 1.2 90/02/26 02:20:42 christos Exp $ */
X/*
X * arrayn.c: Dynamic memory allocator for an n - dimensional array.
X *
X * $Log: arrayn.c,v $
X * Revision 1.2 90/02/26 02:20:42 christos
X * ANSI conformance.
X *
X * Revision 1.1 89/09/08 02:23:03 christos
X * Initial revision
X *
X */
X#ifndef lint
Xstatic char rcsid[] = "$Id: arrayn.c,v 1.2 90/02/26 02:20:42 christos Exp $";
X#endif /* lint */
X
X#ifdef DEBUG
X#include <stdio.h>
X#endif /* DEBUG */
X
X#ifndef __STDC__
X#include <varargs.h>
Xextern char *malloc();
Xtypedef char genptr_t;
X#else
X#include <stdarg.h>
Xextern void *malloc(unsigned n);
Xtypedef void genptr_t;
X#endif
X
Xtypedef unsigned long u_long;
X
Xtypedef struct _dimension_t {
X u_long size; /* Number of elements in the dimension */
X u_long totalsize; /* Total number of elements */
X u_long elsize; /* Size of a single element in bytes */
X u_long offset; /* offset from beginning of array */
X} dimension_t;
X
X/* arrayn():
X * Allocate an n-dimensional array.
X * We want to allocate only one chunk, so that free
X * will free the whole array.
X */
X#ifndef __STDC__
Xchar *
X/*VARARGS*/
Xarrayn(numdim, va_alist)
Xint numdim; /* Number of dimensions */
Xva_dcl
X#else
Xvoid *
Xarrayn(int numdim, ...)
X#endif
X{
X int i, j;
X dimension_t *dim; /* Info about each dimension */
X u_long total_size, /* Total size of the array */
X pointer_size, /* Pointer size of the array */
X element_size; /* Element size of the array */
X genptr_t *array; /* the multi-dimensional array */
X genptr_t **ptr, *data; /* Pointer and data offsets */
X va_list va; /* Current pointer in the argument list */
X
X#ifndef __STDC__
X va_start(va);
X#else
X va_start(va, numdim);
X#endif
X
X if ( (dim = (dimension_t *)
X malloc( (unsigned) (numdim * sizeof(dimension_t))))
X == (dimension_t *) 0 )
X return((genptr_t *) 0);
X
X for ( i = 0; i < numdim; i++ ) {
X dim[i].size = va_arg(va, u_long);
X dim[i].elsize = sizeof(genptr_t *);
X }
X dim[numdim-1].elsize = va_arg(va, u_long);
X
X va_end(va);
X
X /*
X * Compute the size of the array to be allocated
X * elements : (x * y * z ... w * elementsize)
X * pointers : (x * pointersize +
X * y * x * pointersize +
X * z * y * x * pointersize ..
X */
X dim[0].totalsize = dim[0].size;
X dim[0].offset = 0;
X for ( i = 1; i < numdim; i++ ) {
X dim[i].totalsize = dim[i-1].totalsize * dim[i].size;
X dim[i].offset = dim[i-1].offset + dim[i-1].totalsize * dim[i-1].elsize;
X }
X
X element_size = dim[numdim-1].offset +
X dim[numdim-1].totalsize * dim[numdim-1].elsize;
X pointer_size = dim[numdim-1].totalsize;
X
X total_size = element_size + pointer_size;
X
X#ifdef DEBUG
X (void) fprintf(stderr, "%20s : %10d\n", "Number of dimensions",
X numdim, numdim);
X (void) fprintf(stderr, "%20s : %10d (%.8x)\n", "Unit size",
X dim[numdim-1].elsize, dim[numdim-1].elsize);
X (void) fprintf(stderr, "%20s : %10d (%.8x)\n", "Size of pointers",
X pointer_size, pointer_size);
X (void) fprintf(stderr, "%20s : %10d (%.8x)\n", "Size of elements",
X element_size, element_size);
X (void) fprintf(stderr, "%20s : %10d (%.8x)\n", "Total size",
X total_size, total_size);
X (void) fprintf(stderr, "\nDimension\tSize\tTotal Size\tOffset\tElement\n");
X for ( i = 0; i < numdim; i++ )
X (void) fprintf(stderr, "%9d\t%4d\t%10d\t%6d\t%7d\n", i, dim[i].size,
X dim[i].totalsize, dim[i].offset, dim[i].elsize);
X#endif /* DEBUG */
X
X /*
X * Allocate space to hold the array
X */
X if ( (array = (genptr_t *) malloc((unsigned) total_size)) ==
X (genptr_t *) 0 ) {
X (void) free((genptr_t *) dim);
X return((genptr_t *) 0);
X }
X
X /*
X * Thread the pointers
X */
X for ( i = 0; i < numdim - 1; i++ ) {
X ptr = (genptr_t **) (array + dim[i].offset);
X data = (genptr_t *) (array + dim[i+1].offset);
X for ( j = 0; j < dim[i].totalsize; j++ )
X ptr[j] = data + j * dim[i+1].elsize * dim[i+1].size;
X }
X
X (void) free((genptr_t *) dim);
X return(array);
X
X} /* end arrayn */
END_OF_FILE
if test 4107 -ne `wc -c <'arrayn.c'`; then
echo shar: \"'arrayn.c'\" unpacked with wrong size!
fi
# end of 'arrayn.c'
fi
if test -f 'bigtest.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'bigtest.c'\"
else
echo shar: Extracting \"'bigtest.c'\" \(3020 characters\)
sed "s/^X//" >'bigtest.c' <<'END_OF_FILE'
X/* $Header: /home/hyperion/mu/christos/src/mine/lib/arrayn/RCS/bigtest.c,v 1.1 89/09/08 02:23:05 christos Exp Locker: christos $ */
X/*
X * bigtest.c: Test for arrayn.
X *
X * $Log: bigtest.c,v $
X * Revision 1.1 89/09/08 02:23:05 christos
X * Initial revision
X *
X */
X#ifndef lint
Xstatic char rcsid[] = "$Id: bigtest.c,v 1.1 89/09/08 02:23:05 christos Exp Locker: christos $";
X#endif /* lint */
X
X#include <stdio.h>
X
Xtypedef struct test_t {
X int i, j, k, l, m;
X} test_t;
X
Xextern char *arrayn();
X
X#define DIMNUM 5
X#define D_I 12
X#define D_J 23
X#define D_K 51
X#define D_L 4
X#define D_M 3
X
Xstatic char *pname;
X
X/*ARGSUSED*/
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i, j, k, l, m;
X test_t *****ptr;
X
X pname = *argv;
X
X if ((ptr = (test_t *****)
X arrayn(DIMNUM, D_I, D_J, D_K, D_L, D_M, sizeof(test_t))) ==
X (test_t *****) 0 ) {
X (void) fprintf(stderr, "%s: Out of memory.\n", pname);
X exit(1);
X }
X
X#ifdef DEBUG
X for ( i = 0; i < D_I; i++ )
X (void) fprintf(stderr, "ptr[%d] = %.8x(%.8x)\n",
X i, &ptr[i], ptr[i]);
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X (void) fprintf(stderr, "ptr[%d][%d] = %.8x(%.8x)\n",
X i, j, &ptr[i][j], ptr[i][j]);
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ )
X (void) fprintf(stderr, "ptr[%d][%d][%d] = %.8x(%.8x)\n",
X i, j, k, &ptr[i][j][k], ptr[i][j][k]);
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ )
X for ( l = 0; l < D_L; l++ )
X (void) fprintf(stderr, "ptr[%d][%d][%d][%d] = %.8x(%.8x)\n",
X i, j, k, l, &ptr[i][j][k][l], ptr[i][j][k][l]);
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ )
X for ( l = 0; l < D_L; l++ )
X for ( m = 0; m < D_M; m++ )
X (void) fprintf(stderr,
X "ptr[%d][%d][%d][%d][%d] = %.8x\n",
X i, j, k, l, m, ptr[i][j][k][l][m]);
X#endif /* DEBUG */
X /*
X * Load each element with unique data
X */
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ )
X for ( l = 0; l < D_L; l++ )
X for ( m = 0; m < D_M; m++ ) {
X ptr[i][j][k][l][m].i = i;
X ptr[i][j][k][l][m].j = j;
X ptr[i][j][k][l][m].k = k;
X ptr[i][j][k][l][m].l = l;
X ptr[i][j][k][l][m].m = m;
X }
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ )
X for ( l = 0; l < D_L; l++ )
X for ( m = 0; m < D_M; m++ )
X if ( ptr[i][j][k][l][m].i != i ||
X ptr[i][j][k][l][m].j != j ||
X ptr[i][j][k][l][m].k != k ||
X ptr[i][j][k][l][m].l != l ||
X ptr[i][j][k][l][m].m != m) {
X (void) fprintf(stderr,
X "%s: element ptr[%d][%d][%d][%d][%d] bad (%d, %d, %d, %d, %d)\n",
X pname, i, j, k, l, m,
X ptr[i][j][k][l][m].i,
X ptr[i][j][k][l][m].j,
X ptr[i][j][k][l][m].k,
X ptr[i][j][k][l][m].l,
X ptr[i][j][k][l][m].m);
X exit(1);
X }
X (void) fprintf(stderr, "arrayn ok.\n");
X exit(0);
X} /* end main */
END_OF_FILE
if test 3020 -ne `wc -c <'bigtest.c'`; then
echo shar: \"'bigtest.c'\" unpacked with wrong size!
fi
# end of 'bigtest.c'
fi
if test -f 'smalltest.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'smalltest.c'\"
else
echo shar: Extracting \"'smalltest.c'\" \(2175 characters\)
sed "s/^X//" >'smalltest.c' <<'END_OF_FILE'
X/* $Header: /home/hyperion/mu/christos/src/mine/lib/arrayn/RCS/smalltest.c,v 1.1 89/09/08 02:23:07 christos Exp Locker: christos $ */
X/*
X * smalltest.c: Test for arrayn.
X *
X * $Log: smalltest.c,v $
X * Revision 1.1 89/09/08 02:23:07 christos
X * Initial revision
X *
X */
X#ifndef lint
Xstatic char rcsid[] = "$Id: smalltest.c,v 1.1 89/09/08 02:23:07 christos Exp Locker: christos $";
X#endif /* lint */
X
X#include <stdio.h>
X
Xtypedef struct test_t {
X int i, j, k;
X} test_t;
X
Xextern char *arrayn();
X
X#define DIMNUM 3
X#define D_I 4
X#define D_J 5
X#define D_K 6
X
Xstatic char *pname;
X
X/*ARGSUSED*/
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i, j, k;
X test_t ***ptr;
X
X pname = *argv;
X
X if ((ptr = (test_t ***) arrayn(DIMNUM, D_I, D_J, D_K, sizeof(test_t))) ==
X (test_t ***) 0 ) {
X (void) fprintf(stderr, "%s: Out of memory.\n", pname);
X exit(1);
X }
X
X#ifdef DEBUG
X for ( i = 0; i < D_I; i++ )
X (void) fprintf(stderr, "ptr[%d] = %.8x(%.8x)\n",
X i, &ptr[i], ptr[i]);
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X (void) fprintf(stderr, "ptr[%d][%d] = %.8x(%.8x)\n",
X i, j, &ptr[i][j], ptr[i][j]);
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ )
X (void) fprintf(stderr, "ptr[%d][%d][%d] = %.8x\n",
X i, j, k, ptr[i][j][k]);
X#endif /* DEBUG */
X
X /*
X * Load each element with unique data
X */
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ ) {
X ptr[i][j][k].i = i;
X ptr[i][j][k].j = j;
X ptr[i][j][k].k = k;
X }
X
X for ( i = 0; i < D_I; i++ )
X for ( j = 0; j < D_J; j++ )
X for ( k = 0; k < D_K; k++ ) {
X#ifdef DEBUG
X (void) fprintf(stderr,
X "ptr[%d][%d][%d] = (%d, %d, %d)\n",
X i, j, k, ptr[i][j][k].i, ptr[i][j][k].j,
X ptr[i][j][k].k);
X#endif /* DEBUG */
X
X if ( ptr[i][j][k].i != i || ptr[i][j][k].j != j ||
X ptr[i][j][k].k != k ) {
X (void) fprintf(stderr,
X "%s: element ptr[%d][%d][%d] bad (%d, %d, %d)\n",
X pname, i, j, k, ptr[i][j][k].i, ptr[i][j][k].j,
X ptr[i][j][k].k);
X exit(1);
X }
X }
X (void) fprintf(stderr, "arrayn ok.\n");
X exit(0);
X} /* end main */
END_OF_FILE
if test 2175 -ne `wc -c <'smalltest.c'`; then
echo shar: \"'smalltest.c'\" unpacked with wrong size!
fi
# end of 'smalltest.c'
fi
echo shar: End of shell archive.
exit 0
--
/------------------------------------------------------------------------\
| Christos Zoulas | 389 Theory Center, Electrical Engineering, |
| christos at ee.cornell.edu | Cornell University, Ithaca NY 14853. |
| christos at crnlee | Phone: Disconnected | Fax: (607) 254 4565 |
More information about the Comp.lang.c
mailing list