[comp.lang.c] Pointer question

apte@helios.cs.duke.edu (Jitendra Apte) (05/10/89)

I like to test pointers passed to routines at the beginning of the routine.
I currently use a macro called CK_PTR() as follows.

--------------------------------------------------------------------------
/* Use only if pointer is not expected to be NULL */
#define CK_PTR(_p_) {\
	if (!(_p_)) {\
		fprintf(stderr, "NULL pointer\n");\
		exit(1);\
	}\
}\

void
routine(p)
	struct xyz_s *		p;
{
	CK_PTR(p);
	...
	...
}
--------------------------------------------------------------------------

This works fine while checking for NULL pointers. However, there are times
when, due to some other bug in the program under develpment, pointers point out
into space, nowhere in particular : eg. p = 0x2

Is there a better way of checking pointers so as to detect such problems? Seems
difficult, because ideally the macro would have to know the limits of address
space which are "legal".

Fangs.
Jitendra.
(Internet) apte@cs.duke.edu; (UUCP) {decvax|ihnp4|allegra}!duke!apte
"Let us save the kid from abortion, so that he can grow up to steal bread,
 rob banks and murder people. Then we can kill him in the electric chair".

hascall@atanasoff.cs.iastate.edu (John Hascall) (05/11/89)

In article <14454@duke.cs.duke.edu> apte@helios.cs.duke.edu (Jitendra Apte) writes:
>I like to test pointers passed to routines at the beginning of the routine.
>I currently use a macro called CK_PTR() as follows....
 
>This works fine while checking for NULL pointers. However, there are times
>when, due to some other bug in the program under develpment, pointers point out
>into space, nowhere in particular : eg. p = 0x2
 
>Is there a better way of checking pointers so as to detect such problems? Seems
>difficult, because ideally the macro would have to know the limits of address
>space which are "legal".
 
   One possible/partial solution is to always reserve a field in every
   structure which contains an indication of the structure type.  If I
   can ``steal'' from VMS here--all (or most all) the control blocks used
   in VMS start out like this (using a CXB [complex buffer] as an example):

		  struct CXB {
		       struct CXB       *cxb$l_fl;
		       struct CXB       *cxb$l_bl;
		       unsigned short    cxb$w_size;
		       unsigned char     cxb$b_type;
		       unsigned char     cxb$b_subtype;
		       ....
                  };

   The type of the particular structure is always at offset 10 (0x0A), in
   this example it would be DYN$C_CXB (0x1b If I recall correctly).

   Not only can this find most (1 chance in 256 of random error) pointers
   which point at some silly location, it can find pointers which point
   to the wrong type of structure.

   Of course this only works for pointers to structures.


   John Hascall
   ISU Comp Center
   (p.s. VMS isn't written in C, just my ``example'' is)

slewis@oregon.uoregon.edu (05/02/90)

Hello netters.

I have a question about pointers.  Well, actually I have a few observations
and I'm not sure if they're correct.  Maybe you can help...

Assume the following variables:

int i,j;
int **p, *a, *b;

Also assume that we have allocated space for a 2D n X m int "array" (p), 
a n-length linear array (a) and an m-length linear array (b) in the 
following manner:

p = (int **) malloc(n*sizeof(int *));
for(i=0; i < n; i++) p[i] = (int *) malloc(m*sizeof(int));

and

a = (int *) malloc(n*sizeof(int));
b = (int *) malloc(m*sizeof(int));

Now, we may use p[i][j], a[i] and b[i] to refer to the elements of these 
arrays.

My understanding is that a[i] is equiv to *(a+i).  Now, this 
implies some strange things, right?  First, since (pointer) addition is
commutative,  a[i] == *(a+i) == i[a].  I've seen this stated before in
this newsgroup.

But are the following assertions true:

1.  p[i][j] == *( *(p+i) + j) == j[p[i]] == j[i[p]] 

2.  a[b[i]] == *( a + *(b+i)) == b[i][a] == i[b][a]

(assuming that b[i] contains a valid [-1 < b[i] < n] number)

If so, I think I understand.  If not, I'm confused.

Scott

chris@mimsy.umd.edu (Chris Torek) (05/03/90)

In article <19515.263eadf8@oregon.uoregon.edu> slewis@oregon.uoregon.edu
writes:
>... are the following assertions true:
>1.  p[i][j] == *( *(p+i) + j) == j[p[i]] == j[i[p]] 
>2.  a[b[i]] == *( a + *(b+i)) == b[i][a] == i[b][a]

Yes, these assertions hold always (even for p declared as `int p[10][4]',
not just `int **p').  (As it happens, the 4BSD PCC-based compiler also
emits better code for j[i[p]] than for p[i][j], at least when p,i,j are
all global.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

karl@haddock.ima.isc.com (Karl Heuer) (05/04/90)

In article <19515.263eadf8@oregon.uoregon.edu> slewis@oregon.uoregon.edu writes:
>[Assuming declarations int i,j; int **p, *a, *b;] My understanding is that
>a[i] is equiv to *(a+i).  Now, this implies some strange things, right?
>First, since (pointer) addition is commutative, a[i] == *(a+i) == i[a].  I've
>seen this stated before in this newsgroup.

Right.

>But are the following assertions true:
>1.  p[i][j] == *( *(p+i) + j) == j[p[i]] == j[i[p]]
>2.  a[b[i]] == *( a + *(b+i)) == b[i][a] == i[b][a]

Looks right to me.  However, I maintain that, outside of the Obfuscated C
Contest, the identity a[i]==i[a] is worse than useless.  Never *ever* use it!

(I argued that X3J11 should have eliminated this misfeature, just as they did
with "a + = 1", but I wasn't convincing enough.)

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint