[comp.lang.c] More pointer arithmatic questions

pardo@uw-june.UUCP (David Keppel) (01/01/88)

Originally I said

>  int	*a, *b;
>	a += b;
>
>gives error messages.  Why?

The answer is "type checking", that it is senseless to add a pointer to
another pointer.  Thank you all for responding.  I am learning (fast! ;-)

It is clear to me that I don't understand pointer typing just quite yet
(ARRGHH!! NOT AGAIN!!, sorry) so I'd like to ask another, related question.
Please (again) send responses directly to me to avoid net clutter.  If
anybody *really* wants to hear what I learn, send me mail & I'll summarize
and tell you.  Here goes  (This is not what prompted my question, I had
this problem once before):

I have an array of pointer to structures scattered all over memory.  I
want to allocate enough contiguous memory to hold the array and all the
structures, pack it all together, and write it out to disk, read it all in,
and have a valid, ready-to-go array of pointers to structures.  I will
attempt to do this by changing all pointers to be offsets from the base
of the contiguous area before writing to disk (or pipe, or wherever) and
adding the base in at the new malloced area.  (I've dropped typing on the
floor for this example, since it adds clutter)

	/* when writing out to file */
	foo = malloc (array_size + n * sizeof(my_struct));
	bcopy(foo, array, array_size);
	for (i = 0;  i < n;  ++i) {
	    bcopy (foo + arraysize + i * sizeof(my_struct),
		array[i], sizeof(my_struct));		/* copy to contig. */
	    *(foo + sizeof(mystruct *) * i) -= foo;	/* convert to delta */
	    /*
	     * The LHS of this causes the i'th element of the array to
	     * be decremented by the base of the malloced area, so that
	     * no matter where the data is reloaded, we can convert the
	     * "delta pointer" back into a pointer.
	     */
	}

	/* when reading back in again */
	foo = malloc (size);
	read (fd, foo, size);
	for (i = 0;  i < n;  ++i) {
	    *(foo + sizeof(mystruct *) * i) += foo;	/* back to pointers */
	}

Is this sufficiently clear (I hope) to demonstrate?  Is this sufficiently
sick that somebody can suggest an alternative?

Anyway, what I _had_ thought was that I should cast "foo" to be of the
same type as "array[i]", namely (my_struct *), thus avoiding type
conflicts.  "foo" really is an address (of the contiguous data) and
(foo + i * sizeof(my_struct *)) is the address of the i'th pointer to
a my_struct.

It doesn't seem to me like these things are *really* integers, but maybe I'm
just looking at things wrong.  Pointer != integer, so why should I be able
to add them?  What if sizeof(int) < sizeof(my_struct *) ?

Now the question:  In to what type should I cast foo? the pointer?
Ok, it's not a pointer anymore when we're done, but it will be one again
some day.  Is this totally bogus C, anyway?  Is it some coincidence of
VAX and Sun architecture (the only machines I've used the above on
extensively) that it works at all?

  ;-D on  (how about "thing @i" meaning delta-pointer to a thing ?-)  Pardo