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