473,480 Members | 1,850 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Another String reversal question

As if we needed another string reversal question.

I have a problem with the following code, that I believe should work.

int StringReverse(char* psz)
{
char *p = psz;
char *q = psz + strlen(psz) - 1;
while (p < q)
{
char tmp = *p;
*p = *q;
*q = tmp;
p++;
q--;
}
return 1;

}

Thing is, when it gets to the *p = *q line, I get an access violation.

Any ideas why, or what I can do to fix this?

Thanks,

Michael

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05
74 4987
On Sun, 21 Dec 2003 12:48:53 -0500, Ron Natalie wrote:
[mod note: setting your newsreader to post with a width of less than 80 columns
will avoid this type of formatting problem.]

"Dhruv" <dh*******@gmx.net> wrote in message
news:pa***************************@gmx.net...
It would be nice if you
could explain what happens on architectures with 'address registers', and
what they actually are?
[...]
The issue was that these architectures could
only index 16-bits worth
of address space at a time, a separate register held the rest of the
address. Without specifically
mandating the one-past-the-end guarantees, it was quite possible that an
object/array could be
placed at the end of a 64K segment. The one past the end address could
roll over to be have
a value LESS than an address inside the array (if the behavior was left
undefined as other outside
the bounds of arrays are even today).
So, I guess adding 1 to the end of the array would mean that the higher
16-bits in the register would get incremented by 1 and the lower 16-bits
would roll back to 0?

[...]
Another issue is while by and large most architectures only trap invalid
acesses when you actually
read or write through pointers to invalid memory, nothing precludes a
machine from trapping when
you manipulate an invalid pointer value. Again you will need the
one-past-the-end guarantee.
This might happen someday when security and reliability become more
important that the current
cavalier Microsoft-induced attitude.


So, isn't one past the end of the array also some memory that the running
process might not bw owning? I have probably misunderstood something here.

Assume this is the array:
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
^ ^ ^
| | |
First element Last |
|
One past last.

Now, do you mean to say that the one past last element of the array is
also opwned by the process?
Regards,
-Dhruv.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #51
On Sun, 21 Dec 2003 12:50:02 -0500, Jeff Schwab wrote:
[...]
Sweet!!! I guess this implies that algorithms meant to work on
collections actually can work on individual elements just as easily.
Good to know.

#include <iostream>
#include <cctype>

int main( )
{
char const* s = "a";
char const c = 'a';

std::cout << std::equal( s, s + 1, &c ) << '\n';
}


Getting a bit picky, I guess s+1 is not the actual end of the array.
However s+2 is right? Or am I mistaken?

Regards,
-Dhruv.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #52
In message <pa****************************@gmx.net>, Dhruv
<dh*******@gmx.net> writes
So, isn't one past the end of the array also some memory that the running
process might not bw owning? I have probably misunderstood something here.

Assume this is the array:
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
^ ^ ^
| | |
First element Last |
|
One past last.

Now, do you mean to say that the one past last element of the array is
also opwned by the process?


The address of one past the last must be owned by the process. Note that
only requires a single extra address in the address range. One before
the start is an entirely different issue which is why it is not
supported.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #53
Si*********@REMOVE.att.net (Siemel Naran) wrote (abridged):
For functions returning an integer, return of zero means no error,
and return of any other number (positive or negative) means error.
Are you sure you want to return 1?


In other conventions, a negative number means an error, and 0 or
positive means success. This is useful when a successful result
needs include something like a file handle, which is an index into
some table. In still others, 0 means false which means failure.

In this case I don't see a need for any result at all, because
StringReverse cannot fail.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #54
On 22 Dec 2003 07:20:35 -0500, "Dhruv" <dh*******@gmx.net> wrote:
So, isn't one past the end of the array also some memory that the running
process might not bw owning? I have probably misunderstood something here.


Yes. The standard requires that the last byte of every address space
owned by the process be unused and available for use as a
one-past-the-end of whatever comes in front of it. The standard
requires that one-past-the-end of any object be a valid address. It
need not be dereferenceable nor the beginning of space large enough
to hold an object of the same type. Why or how the implementation
does it is not important to a programmer. It is a guarantee.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #55
Dhruv wrote:
On Sun, 21 Dec 2003 12:50:02 -0500, Jeff Schwab wrote:
[...]

Sweet!!! I guess this implies that algorithms meant to work on
collections actually can work on individual elements just as easily.
Good to know.

#include <iostream>
#include <cctype>

int main( )
{
char const* s = "a";
char const c = 'a';

std::cout << std::equal( s, s + 1, &c ) << '\n';
}

Getting a bit picky, I guess s+1 is not the actual end of the array.
However s+2 is right? Or am I mistaken?


You're right that s + 2 is the end of the array, but in this case, I
wasn't looking for the end of the array. I was only comparing one
character.

-Jeff

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #56
"Ron Natalie" <ro*@sensor.com> wrote in message
news:<3f*********************@news.newshosting.com >...
"Dhruv" <dh*******@gmx.net> wrote in message
news:pa***************************@gmx.net...
It would be nice if you could explain what happens on architectures
with 'address registers', and what they actually are?
This whole "one-past-the-end" issue came from a very real environment
that was in popular use at the time the C standard was originally
being hammered out. It was the 80x86 segmented (pre-386)
architectures.
[...]
Another issue is while by and large most architectures only trap
invalid acesses when you actually read or write through pointers to
invalid memory, nothing precludes a machine from trapping when you
manipulate an invalid pointer value. Again you will need the
one-past-the-end guarantee. This might happen someday when security
and reliability become more important that the current cavalier
Microsoft-induced attitude.
Why do you say pre-386? The only large application I did on an 80386
used 48 bit segmented pointers. Every malloc returned a different
segment, and segment selectors were invalidated when the memory was
returned by free. Loading an invalid segment selector into a segment
register provoked a hardware trap. And the code generated by the
compiler to read an address from memory was the instruction LES, LFS or
LGS. So something like:

free( p ) ;
if ( p == NULL )

really did trap. (On the other hand, there was no problem with 2 past
the end, or one before the beginning, as long as one didn't
dereference.)
Believe me, it can happen and be best to make your application clean
against reliance on undefined behavior. Lots of heartburn when apps
were ported to the first 64 bit architectures in common use in micros
(Alpha) because people assumed a things like the size of pointers and
the various other types. We also had fun because while most machines
trap only computations involving invalid floating point numbers, the
Alpha (which was fine by the language) trapped even loading invalid
floats into the fp registers. Our bad for assuming we could put
(possibly) garbage values into float variables. We had to clean that
up.


Interesting. I first encountered that problem on Interdata 8/32, in
1977. (Hardly new:-).) And consider yourself luck you got a trap; in
our case, the hardware would normalize floating point values on a load.
One of the programmers had "optimized" his copy loops to use double* for
text data, in order to pass through the loop less times. The 8/32 used
IBM format floating point; most of the time, there was no problem, but
if the second byte in the double happened to be a control character
(with the top four bits 0), all of the bytes in the mantissa were
shifted left 4 bits, and the exponent was decremented. Obviously, the
character values after that were somewhat unexpected. But legitimate
character data would never cause a trap.

That's what's fun about undefined behavior. You never know what it
might do:-).

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #57
Francis Glassborow <fr*****@robinton.demon.co.uk> wrote in message
news:<7v**************@robinton.demon.co.uk>...
In message
<6v***********************@bgtnsc04-news.ops.worldnet.att.net>, Siemel
Naran <Si*********@REMOVE.att.net> writes
Yes, for functions returning bool the convention is true means
success (and true maps to a non-zero integer). And third, functions
could throw to signify an error. For functions returning int the
convention is zero means success.
I think that I probably have an unusually extensive reading of
relevant literature but cannot recall any such statement being made by
good, bad or indifferent authors. Perhaps you could jog my memory with
a few references.
With regards to functions returning int, there are a few conventions
established by the C standard: for the functions in ctype, for example,
0 means failure, as does NULL (a type of zero) for fopen. On the other
hand, many of the IO functions will return the number of characters
transmitted (with 0 as a valid value), or a negative value for failure.
While I would give 'use bool to report success/failure' as a very
strong guideline, it is not an option when writing code that needs to
be compatible to all versions of C and to C++ so I continue to have
strong doubts that any convention such as the one you claim exists in
the wider C & C++ programming community.
I rather prefer something along the lines of "enum ReturnCode { ok,
error } ;". I'd prefer it even more if there were no implicit
conversion to bool. While true == success seems more reasonable than
the reverse to me as well, I've had to deal with code which used the
other convention. Whereas "return ok", or "if ( func() == ok )" is
perfectly clear in every case.
Note that zero denotes success for return from main, and it also does so
for comparison functions passed to qsort and bsearch but it does not do
so for comparison functions passed to the various C++ sort and search
functions.


There is no error return value for the comparison functions passed to
qsort and bsearch.

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #58
On Mon, 22 Dec 2003 09:11:56 -0500, Francis Glassborow wrote:

[...]
The address of one past the last must be owned by the process. Note that
only requires a single extra address in the address range. One before
the start is an entirely different issue which is why it is not
supported.


Then how are reverse iterators supposed to work?

Regards,
-Dhruv.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #59
dh*******@gmx.net (Dhruv) wrote (abridged):
So, I guess adding 1 to the end of the array would mean that the
higher 16-bits in the register would get incremented by 1 and
the lower 16-bits would roll back to 0?
With some hardware, the higher 16 bits would be unchanged. Pointer
arithmetic only affected the low 16-bits; the CPU might not even
have been capable of 32-bit arithmetic directly.

Thus (char *) 0x1001ffff + 1 = (char *) 0x10010000 for these pointers,
and p > p+1.

(For some compilers, only the low 16 bits took part in pointer
comparisons, but this wasn't ratified by the standard. It meant
(char *)0x10014444 == (char *) 0x20024444, and you had to be
sure you had the right kind of NULL. Unpleasant.)

So, isn't one past the end of the array also some memory that the
running process might not bw owning?


It could be, but the C++ standard requires that the compiler make it
work. This may mean allocating one more byte than necessary. In
practice for alignment reasons you may need several bytes, but there
doesn't have to be a whole object there. In that respect your diagram
is misleading.

To allow one before the beginning, we would need sizeof(object) bytes,
which is more onerous because an object can be arbitrarily large.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #60
Dhruv wrote:
On Mon, 22 Dec 2003 09:11:56 -0500, Francis Glassborow wrote:

[...]

The address of one past the last must be owned by the process. Note that
only requires a single extra address in the address range. One before
the start is an entirely different issue which is why it is not
supported.

Then how are reverse iterators supposed to work?


Supposed by whom? These rules were in place long before there was an STL.

A reverse iterator actually works by associating itself with one element
higher than what you'd think. When you try to convert between forward
and reverse iterators, you don't get what you might expect.

-Jeff

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #61

"Dhruv" wrote
ok, no because as John Potter mentioned that the delete expression is
allowed to modify the pointer passed to it,
No, he didn't. He said the delete expression invalidates the pointer
passed to it. The pointer is not changed, but it is no longer a valid pointer.
so I was just wondering how it
would modify a constant passed to it. But now that you've mentioned that
C++ guarantees a Null operation, there's nothing wrong with it.


Regards,
Buster

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #62

"Dhruv" <dh*******@gmx.net> wrote in message
news:pa****************************@gmx.net...
On Mon, 22 Dec 2003 09:11:56 -0500, Francis Glassborow wrote:

[...]
The address of one past the last must be owned by the process. Note that
only requires a single extra address in the address range. One before
the start is an entirely different issue which is why it is not
supported.


Then how are reverse iterators supposed to work?


The base pointer of a reverse iterator points to a location one past
the location conceptually pointed to by the reverse iterator. Simple.

Regards,
Buster.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #63
"Dhruv" <dh*******@gmx.net> wrote in message
news:<pa****************************@gmx.net>...
On Sun, 21 Dec 2003 12:48:53 -0500, Ron Natalie wrote:
"Dhruv" <dh*******@gmx.net> wrote in message
news:pa***************************@gmx.net...
It would be nice if you could explain what happens on
architectures with 'address registers', and what they actually are? [...]

The issue was that these architectures could only index 16-bits
worth of address space at a time, a separate register held the rest
of the address. Without specifically mandating the one-past-the-end
guarantees, it was quite possible that an object/array could be
placed at the end of a 64K segment. The one past the end address
could roll over to be have a value LESS than an address inside the
array (if the behavior was left undefined as other outside the
bounds of arrays are even today). So, I guess adding 1 to the end of the array would mean that the
higher 16-bits in the register would get incremented by 1 and the
lower 16-bits would roll back to 0?
No. The lower 16 bits would wrap to 0, and the higher 16 bits would
remain unchanged.

Note that this is standard segmented architecture. And that it is still
true for modern Intel processors, if you replace lower 16 bits with
lower 32 bits. While some widespread architectures artificially limit
the Intel to linear addressing, the processor is capable of much more,
and I've worked with systems using 48 bit addresses.

The result is that the hardware will allow an object with 2^32 bytes,
but C and C++ won't (because the address of the object plus one would
not be greater than the address of the object).
[...] Another issue is while by and large most architectures only trap
invalid acesses when you actually read or write through pointers to
invalid memory, nothing precludes a machine from trapping when you
manipulate an invalid pointer value. Again you will need the
one-past-the-end guarantee. This might happen someday when security
and reliability become more important that the current cavalier
Microsoft-induced attitude.

So, isn't one past the end of the array also some memory that the
running process might not bw owning? I have probably misunderstood
something here. Assume this is the array:
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
^ ^ ^
| | |
First element Last |
|
One past last. Now, do you mean to say that the one past last element of the array is
also opwned by the process?


The C and the C++ standards require the implementation to allow the
existance of such addresses. How they do so is their problem. If
loading such an address in an address register would trap, either the
implementation must ensure that it never generates code to load it into
an address register, or (more frequently), it must ensure that there is
an extra addressable byte behind each object.

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #64
Francis Glassborow <fr****************@robinton.demon.co.uk> wrote in
message news:<rD**************@robinton.demon.co.uk>...
In message <pa****************************@gmx.net>, Dhruv
<dh*******@gmx.net> writes
So, isn't one past the end of the array also some memory that the
running process might not bw owning? I have probably misunderstood
something here. Assume this is the array:
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
^ ^ ^
| | |
First element Last |
|
One past last. Now, do you mean to say that the one past last element of the array
is also opwned by the process?
The address of one past the last must be owned by the process.


No. The implementation must ensure that I can read the address value
(but not necessarily dereference it). Owning one additional byte is one
possible solution -- not loading the address into an address register
unless it is going to be dereferenced is another.

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #65
In message <pa****************************@gmx.net>, Dhruv
<dh*******@gmx.net> writes
Then how are reverse iterators supposed to work?


with difficulty:-) Which is exactly why they are provided by Standard
containers. Effectively they dereference the iterator value 'before'
before the one being 'held' that means when they get to the 'first'
(i.e. rend()) they stop because there is nothing before it.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #66
In message <d6**************************@posting.google.com >,
ka***@gabi-soft.fr writes
There is no error return value for the comparison functions passed to
qsort and bsearch.


Yes, we both know that but countless programmers think in terms of
checking if two things are equal and so consider the zero return to be
'success'.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #67
ka***@gabi-soft.fr writes:

[...]

| > The address of one past the last must be owned by the process.
|
| No. The implementation must ensure that I can read the address value
| (but not necessarily dereference it). Owning one additional byte is one
| possible solution -- not loading the address into an address register
| unless it is going to be dereferenced is another.

comparaison may need to load the pointer into address register too.

--
Gabriel Dos Reis
gd*@integrable-solutions.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #68
On Tue, 23 Dec 2003 11:56:52 -0500, Francis Glassborow wrote:
In message <pa****************************@gmx.net>, Dhruv
<dh*******@gmx.net> writes
Then how are reverse iterators supposed to work?


with difficulty:-) Which is exactly why they are provided by Standard
containers. Effectively they dereference the iterator value 'before'
before the one being 'held' that means when they get to the 'first'
(i.e. rend()) they stop because there is nothing before it.


Oh! Ingenious.

Regards,
-Dhruv.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #69
"Jeff Schwab" <je******@comcast.net> wrote in message
news:ZvKdnX6ysZ-pO3qiRVn-
A iterator actually works by associating itself with one element
higher than what you'd think. When you try to convert between forward
and reverse iterators, you don't get what you might expect.


That depends on what you're trained to expect.

--
+++++++++++
Siemel Naran
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #70
Siemel Naran wrote:
"Jeff Schwab" <je******@comcast.net> wrote

A iterator actually works by associating itself with one element
higher than what you'd think. When you try to convert between forward
and reverse iterators, you don't get what you might expect.

That depends on what you're trained to expect.


Certainly true! Like I said, what you *might* expect. :)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #71
Gabriel Dos Reis <gd*@integrable-solutions.net> wrote in message
news:<m3************@uniton.integrable-solutions.net>...
ka***@gabi-soft.fr writes: [...] | > The address of one past the last must be owned by the process. | No. The implementation must ensure that I can read the address
| value (but not necessarily dereference it). Owning one additional
| byte is one possible solution -- not loading the address into an
| address register unless it is going to be dereferenced is another. comparaison may need to load the pointer into address register too.


In that case, the implementation must allocate one extra byte. It's
never been the case with any hardware I've used. In fact, if I remember
right, on a Motorola 68000 (or maybe it was some other processor), the
hardware didn't support comparison of address registers. Which was a
pain: if you wrote something like:
if ( p != NULL && *p != '\0') ...
the compiler had to put p in different registers in each of the two
parts of the expression.

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #72
Francis Glassborow <ju***@robinton.demon.co.uk> wrote in message
news:<j8**************@robinton.demon.co.uk>...
In message <d6**************************@posting.google.com >,
ka***@gabi-soft.fr writes
There is no error return value for the comparison functions passed to
qsort and bsearch.
Yes, we both know that but countless programmers think in terms of
checking if two things are equal and so consider the zero return to be
'success'.


But not the authors of qsort or bsearch:-).

I do know that some programmers tend to think of strcmp as meaning
strequ. With sometimes disasterous results:

if ( strcmp( a, b ) )
// Strings are equal...

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #73
Francis Glassborow <ju***@robinton.demon.co.uk> wrote in message
news:<t8**************@robinton.demon.co.uk>...
In message <pa****************************@gmx.net>, Dhruv
<dh*******@gmx.net> writes
Then how are reverse iterators supposed to work?
with difficulty:-) Which is exactly why they are provided by Standard
containers. Effectively they dereference the iterator value 'before'
before the one being 'held' that means when they get to the 'first'
(i.e. rend()) they stop because there is nothing before it.


Note that long before the STL, it was standard practice in C to use half
open intervals -- the standard loop over an array, for example, was:

for ( int i = 0 ; i < arraySize ; i ++ )
doSomethingWith( array[ i ] ) ;

Applying this logic to reverse "iterators" (where iterator is used to
mean anything used to designate an element, including indexes): the
iterator designates the top end, which is the open open end of the
interval. Thus, the standard reverse loop was:

for ( int i = arraySize ; i > 0 ; i -- )
doSomethingWith( array[ i - 1 ] ) ;

At least, that was the way I always wrote it, even back in my C days.
In the case of a while loop, when iterating up, the incrementation is at
the end of the loop; when iterating down, the decrementation is the
first instruction in the loop.

All of this seems something trivially obvious to me. The while loop
handling was the standard procedure in Pascal and Modula-2 (before I
started using C) -- for loops are somewhat limited in those languages,
and aren't used much.

What's the point in starting array indexes at 0 otherwise?

Anyway, reverse iterators in the STL only encapsulate this standard
technique. They are nice syntactic sugar, but there's hardly any "with
difficulty" -- they just use the standard idioms that every one has used
for ages.

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #74
On Wed, 24 Dec 2003 13:51:14 -0500, kanz wrote:

[...]
Anyway, reverse iterators in the STL only encapsulate this standard
technique. They are nice syntactic sugar, but there's hardly any "with
difficulty" -- they just use the standard idioms that every one has used
for ages.


That's exactly the problem with me. I've been around for just 19 something
years since the time I was 'instantiated' ;-)
Merry Christmas,
-Dhruv.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #75

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

45
5263
by: Rakesh | last post by:
Hi, I have this function to reverse the given string. I am just curious if that is correct and there could be better way of doing it / probable bugs in the same. The function prototype is...
12
1690
by: Sathyaish | last post by:
How would you reverse a string "in place" in python? I am seeing that there are a lot of operations around higher level data structures and less emphasis on primitive data. I am a little lost and...
41
3334
by: rick | last post by:
Why can't Python have a reverse() function/method like Ruby? Python: x = 'a_string' # Reverse the string print x Ruby: x = 'a_string' # Reverse the string
3
6081
by: steezli | last post by:
Hi, Brand new to VB.NET and I'm having a problem figuring out this program. I'll try and be descritive as possible. I have to create a Windows application that contains a single top-level...
0
7041
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7044
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6739
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
6929
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5337
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
4779
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
2995
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
2984
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1300
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.