If I'm not mistaken, it accesses one past the end whenever number > 0, but replacing the for statement with
should fix it.Code:for(x = 0; x < --number; x++) {
Edit: Actually, it's not just a one-past-the-end problem, but that number is one too high. Since x and number represent indices to the first and second elements to be swapped, and they start at the beginning and one past the end, resp., x should be incremented at the end of the body, and number decremented at the beginning.
Edit: Pointer version:
Code:void reverse_array(int *p1, int *p2) { int tmp; if (p1 == p2) return; while (p1 < --p2) { tmp = *p1; *p1++ = *p2; *p2 = tmp; } }
Last edited by robatino; 03-30-2007 at 10:28 PM.
Well to be truthful, it's a very odd function. How are you calling it? Passing the head and tail of the array? The head and one-past the tail of the array (which you're not allowed to do really, as the only way you're supposed to ever use that is as a comparison to its value).
I like the "start of array, and its size" as arguments better myself. At the same time I understand the need to keep one's self entertained.
Quzah.
Hope is the first step on the road to disappointment.
Well I think you're OK with it. There was quite a lengthy discussion on the topic here one time. But who knows if that thread is even in the database any more due to crashes / thread loss. It went something like this:
I can't remember it all, and I'm too tired to look it up now. But there was quite a bit of discussion on what you can and can't do with an array's "one past" element / address.Code:if( p < array + len ) /* ok */ p2 = array + len; if( p < p2 ) /* probably ok */
Quzah.
Last edited by quzah; 03-31-2007 at 02:20 AM.
Hope is the first step on the road to disappointment.
As I understand it, any two pointers to the same array between the start and one past the end, inclusive, can be compared or subtracted from each other, so both of your examples should be good. Also, any of these pointers except the one past the end can be dereferenced. My function was written to imitate the C++ Standard Library's interface, using pointers/iterators to the beginning and one past the end of a container (it has to be one past the end to allow zero-length containers).
Quzah et al are right, my code doesn't work some of the time. robatino's fix works.
Strangely enough, I think that the one-past-end pointer can only be compared with equality, not < or >. This is so that you can have an array at the very end of memory; one-past-the-end would wrap around to zero. You could still == and != it but < and > wouldn't work. It would probably be a good idea to dig up the thread Quzah mentioned.As I understand it, any two pointers to the same array between the start and one past the end, inclusive, can be compared or subtracted from each other, so both of your examples should be good. Also, any of these pointers except the one past the end can be dereferenced.
And all of this because of the simple question, "How do you reverse an array?"
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
I don't think this is correct, since it's not really necessary to allow an array at the very end of memory, because it would only save a few bytes, at the expense of losing the ability to do a general compare with one-past-the-end. I don't have a copy of the Standard, but did some googling, and found the following links:
http://c0x.coding-guidelines.com/6.5.6.html
http://archives.devshed.com/forums/d...s-1151250.html
The second link basically claims something I never heard of, which is that although the result of pointer subtraction is ptrdiff_t (defined in <stddef.h>), which I knew, it's not guaranteed that ptrdiff_t is actually big enough to hold the result of the subtraction (!), and that if it isn't, the result is undefined. What this seems to mean is that one can't reliably do pointer subtraction at all, but just comparisons <, <=, >, >=, ==, != (as long as both pointers point to elements of the same array, or one-past-the-end of the array). But I'm pretty sure that the one-past-the-end pointer has the same status as the other elements of an array as far as these comparisons is concerned. Can someone with a copy of the Standard find some relevant passages?
9 When two pointers are subtracted, both shall point to elements of the same array object,
or one past the last element of the array object; the result is the difference of the
subscripts of the two array elements. The size of the result is implementation-defined,
and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header.
If the result is not representable in an object of that type, the behavior is undefined.
Quzah.
Hope is the first step on the road to disappointment.