Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!umd5!mimsy!chris
From: chris@mimsy.UUCP (Chris Torek)
Newsgroups: comp.lang.c
Subject: Re: Dynamic multidimensional arrays
Message-ID: <11973@mimsy.UUCP>
Date: 15 Jun 88 14:52:53 GMT
References: <10655@agate.BERKELEY.EDU> <1857@hubcap.UUCP> <4556@haddock.ISC.COM> <3342@ut-emx.UUCP>
Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742
Lines: 43

In article <3342@ut-emx.UUCP> chpf127@ut-emx.UUCP (J. Eaton) writes:
>What if I decide I would like to have negative as well as positive
>(or zero) indices for arrays?
>
>Standard Fortran allows this.  Doesn't C?

Well, yes and no.  You can portably use nonzero array origins if and
only if the zero point is contained within the array.  If not, you get
into some shady areas, where the code will work on most machines and in
most cases, but is not guaranteed.

To get an array of type `ty' that ranges from LOW to HIGH, where
LOW <= 0 and HIGH > 0, write

	ty actual_array[HIGH-LOW];
	#define array (&actual_array[-LOW])

	... work with array[k], where LOW <= k < HIGH ...

or

	ty *actual_ptr, *ptr;

	actual_pointer = (ty *)malloc((HIGH-LOW) * sizeof(ty));
	if (actual_pointer == NULL) ... no memory;

	ptr = actual_ptr - LOW;	/* nb. LOW nonpositive, so ptr>=actual_ptr */
	... work with ptr[k], where LOW <= k < HIGH ...
	free(actual_ptr);

	/*
	 * N.B.: this can be done with a single pointer.
	 * If cheating with a positive LOW, the result
	 * might happen to == NULL.
	 */

This code generally works even with LOW positive, but the address
computed for `ptr' above is outside of the address space returned by
malloc(); whether this causes a fault or other misbehaviour is
implementation-dependent.  If it happens to be equal to (ty *)NULL,
the runtime system might `helpfully' catch it.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris