ptrs and arrays

Chris Torek chris at mimsy.umd.edu
Fri Nov 10 14:55:44 AEST 1989


>In article <2640 at dogie.macc.wisc.edu> yahnke at vms.macc.wisc.edu
>(Ross Yahnke, MACC) writes:
>>... I want to [malloc and] access [a chunk of memory]
>>as an integer array and inc different elements of the array.

In article <304 at jhereg.Minnetech.MN.ORG> mark at jhereg.Minnetech.MN.ORG
(Mark H. Colburn) writes:
>What you really want is something like this:
>
>   { 
>	int	**aPtr;
>	char     *calloc();
>
>	aPtr = (int **)calloc(10, sizeof(int));
>	aPtr[10]++;
>   }

Mark, you should know better than this (especially since we just went
through this in this very newsgroup).  For what Ross described, he
wants something like

	int i, n;
	int *b; /* base of the chunk of memory */

	n = how_ever_many_we_want();
	b = (int *)malloc(n * sizeof(int));
	/*
	 * or
	b = (int *)calloc(n, sizeof(int));
	 */
	if (b == NULL) {
		help, allocation failed, call in the Marines,
		call the President, dump core!
	}
	/*
	 * The following is unnecessary with calloc, but
	 * only for certain kinds of data (bytes and things
	 * made up of integral bytes, as opposed to weird
	 * bytes like those in pointers or float or double).
	 */
	for (i = 0; i < n; i++)
		b[i] = 0;
	/*
	 * now `b[k]++' is legal for all k in [0..n).
	 */

>Using the "int **" for the data type, you are allocating space for an
>array of ints, and acessing it as such...

malloc (and calloc, which is simply a wrapper for malloc+memset)
simply obtains a `lump' of memory.  In principle, the cast, or if
there is no cast, the variable, to the left of the call to malloc
gives that lump its shape.  That shape must match up, in some way,
to the number of bytes requested.

To do the matching, take the type---(int **), (int *), or whatever;
no matter what, it will be some sort of `pointer to T'---and take
out the `pointer to' part.  If the call is, for instance,

	p = (thistype *) malloc( ...

the type is `pointer to thistype', so take out the `pointer to' and
get `thistype'.  Now look at the argument to malloc, or the second
argument to calloc.  It had better be `sizeof(T)', or some multiple
of sizeof(T):

	p = (thistype *) malloc( sizeof(thistype) ); /* right */
	p = (thistype *) calloc( 1, sizeof(thistype) ); /* right */
	p = (thistype *) malloc( n * sizeof(thistype) ); /* right */
	p = (thistype *) calloc( n, sizeof(thistype) ); /* right */
	p = (thistype *) calloc( 1, n * sizeof(thistype) ); /* a bit weird,
							but otherwise OK */
	p = (thistype *) malloc( 123 );	/* wrong */
	p = (thistype *) malloc( sizeof(othertype) ); /* wrong */
	p = (thistype *) malloc( sizeof(thistype *) ); /* wrong */

This applies no matter how many stars there are:

	p = (foo **) malloc( ...

Here the type is `pointer to pointer to foo', so take out the (first)
`pointer to', and get `pointer to foo'.  The argument to malloc had
better be sizeof(foo *), or some multiple thereof:

	p = (foo **) malloc( n * sizeof(foo *) ); /* right */
	p = (foo **) malloc( n * sizeof(foo) ); /* wrong */

If the type and size do not match up in this fashion, the run-time
behaviour of the code is undefined.  (Your computer might call in the
Marines, then dump core all over them; this might make them rather mad
at you, and you probably would not want that. :-) )

But that is not the only problem with this code:

>	aPtr = (int **)calloc(10, sizeof(int));

The type and size do not match up.  If we had

	aPtr = (int **)calloc(10, sizeof(int *));

they would, and aPtr[i] would have type=`int *' and value=junk; or
if we changed the declaration of `aPtr' to `int *aPtr' and changed
the code to

	aPtr = (int *)calloc(10, sizeof(int));

they would again, and aPtr[i] would have type=`int' and value=0.
But:

>	aPtr[10]++;

aPtr would only point to the first of ten `int's, and aPtr[10] names
the eleventh such `int'.  (The first 10 are numbered 0 through 9.)
Again, the behavour is undefined, and who knows what mean old Mr.
Computer would do this time, like maybe call the CIA and report you
for selling secrets to the Russians....

Oops, I see it is time for my medication :-)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list