Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!purdue!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: ptrs and arrays Message-ID: <20670@mimsy.umd.edu> Date: 10 Nov 89 03:55:44 GMT References: <2640@dogie.macc.wisc.edu> <304@jhereg.Minnetech.MN.ORG> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 121 >In article <2640@dogie.macc.wisc.edu> yahnke@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@jhereg.Minnetech.MN.ORG> mark@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@cs.umd.edu Path: uunet!mimsy!chris