By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,901 Members | 1,270 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,901 IT Pros & Developers. It's quick & easy.

Incrementing a pointer to a one-past-the-end value?

P: n/a
I wonder if the C++ standard says what should happen if I increment a
pointer to a one-past-the-end value.
I think it says that it is perfectly legal to increment a pointer to
the last element element in an array - I get a pointer to
one-past-the-end value. It is guaranteed that such a value exists for
any array, so I always get a valid pointer to something (I do not care
what it is).
So, my question is what if I go further and increment a pointer to a
one-past-the-end value? Do I still get a valid pointer to anything?
Let me illustrate my question with a piece of code:

int main
(
)
{
int a[ 2 ];
int* p = a;
++p; // OK, points to the second element (indexed 1).
++p; // OK, points to one-past-the-end value.
++p; // What happens here? Is p a valid pointer? And what if the array
was allocated dynamically?
}

Jul 27 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
BigMan wrote in
news:11**********************@g14g2000cwa.googlegr oups.com in
comp.lang.c++:
So, my question is what if I go further and increment a pointer to a
one-past-the-end value? Do I still get a valid pointer to anything?
Let me illustrate my question with a piece of code:

int main
(
)
{
int a[ 2 ];
int* p = a;
++p; // OK, points to the second element (indexed 1).
++p; // OK, points to one-past-the-end value.
++p; // What happens here? Is p a valid pointer? And what if the
array
was allocated dynamically?
You have undefined behaviour, IOW the standard no longer defines what
will or will not happen, it could be Very Bad Things(tm) or nothing
at all.
}


HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 27 '05 #2

P: n/a
I think this is enough. Thanks!

Jul 27 '05 #3

P: n/a
Rob Williscroft wrote:
BigMan wrote in
news:11**********************@g14g2000cwa.googlegr oups.com in
comp.lang.c++:

So, my question is what if I go further and increment a pointer to a
one-past-the-end value? Do I still get a valid pointer to anything?
Let me illustrate my question with a piece of code:

int main
(
)
{
int a[ 2 ];
int* p = a;
++p; // OK, points to the second element (indexed 1).
++p; // OK, points to one-past-the-end value.
++p; // What happens here? Is p a valid pointer? And what if the
array
was allocated dynamically?

You have undefined behaviour, IOW the standard no longer defines what
will or will not happen, it could be Very Bad Things(tm) or nothing
at all.


Surely he only has undefined behaviour if he actually dereferences it?

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 27 '05 #4

P: n/a
Ben Pope wrote in news:1122484994.3755e373a8cc924c5c567c3e34651725@t eranews
in comp.lang.c++:
Rob Williscroft wrote:
BigMan wrote in
news:11**********************@g14g2000cwa.googlegr oups.com in
comp.lang.c++:

So, my question is what if I go further and increment a pointer to a
one-past-the-end value? Do I still get a valid pointer to anything?
Let me illustrate my question with a piece of code:

int main
(
)
{
int a[ 2 ];
int* p = a;
++p; // OK, points to the second element (indexed 1).
++p; // OK, points to one-past-the-end value.
++p; // What happens here? Is p a valid pointer? And what if the
array
was allocated dynamically?

You have undefined behaviour, IOW the standard no longer defines what
will or will not happen, it could be Very Bad Things(tm) or nothing
at all.


Surely he only has undefined behaviour if he actually dereferences it?


If it isn't undefined, then surely it must be defined, so what does it
do ?

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 27 '05 #5

P: n/a
Ben Pope wrote:
Rob Williscroft wrote:
BigMan wrote:

int main
(
)
That's a new indenting style..
{
int a[ 2 ];
int* p = a;
++p; // OK, points to the second element (indexed 1).
++p; // OK, points to one-past-the-end value.
++p; // What happens here?

You have undefined behaviour, IOW the standard no longer defines what
will or will not happen, it could be Very Bad Things(tm) or nothing
at all.


Surely he only has undefined behaviour if he actually dereferences it?


No, the increment itself causes undefined behaviour.

As a rationale, consider these possibilities:
- a[] is the last object in memory (or the current segment)
- a+3 would be in a different process's address space

These possibilities are unlikely on an IA32 system with 4 Gigabytes
of RAM, but they are much more real on an embedded system.

Jul 27 '05 #6

P: n/a
Rob Williscroft wrote:
Ben Pope wrote in news:1122484994.3755e373a8cc924c5c567c3e34651725@t eranews
in comp.lang.c++:

Rob Williscroft wrote:
BigMan wrote in
news:11**********************@g14g2000cwa.googl egroups.com in
comp.lang.c++:

So, my question is what if I go further and increment a pointer to a
one-past-the-end value? Do I still get a valid pointer to anything?
Let me illustrate my question with a piece of code:

int main
(
)
{
int a[ 2 ];
int* p = a;
++p; // OK, points to the second element (indexed 1).
++p; // OK, points to one-past-the-end value.
++p; // What happens here? Is p a valid pointer? And what if the
array
was allocated dynamically?
You have undefined behaviour, IOW the standard no longer defines what
will or will not happen, it could be Very Bad Things(tm) or nothing
at all.


Surely he only has undefined behaviour if he actually dereferences it?

If it isn't undefined, then surely it must be defined, so what does it
do ?


I guessed the pointer was equal to a + 3*sizeof(int), regardless of what is or isn't there, but presumably it doesn't, which is why dereferencing it is bad.

presumably thats why:
std::vector<int> v;
std::vector<int>::iterator i = v.begin();
i--;
i++;

Isn't guaranteed to point to *v.begin()?

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 28 '05 #7

P: n/a
Ben Pope wrote in
news:1122540209.1629051a7bcb71987b0faeff0f5fb4f8@t eranews in
comp.lang.c++:
> int* p = a;
> ++p; // OK, points to the second element (indexed 1).
> ++p; // OK, points to one-past-the-end value.
> ++p; // What happens here? Is p a valid pointer? And what if
> the array
>was allocated dynamically? Surely he only has undefined behaviour if he actually dereferences
it?

If it isn't undefined, then surely it must be defined, so what does
it do ?


I guessed the pointer was equal to a + 3*sizeof(int), regardless of
what is or isn't there, but presumably it doesn't, which is why
dereferencing it is bad.


There are implementations where you have ((p + n) - n) == p, for
any non-void pointer p and any int n. There are other implementations
where a pointer (in a register) that doesn't actually point to valid
memory causes some kind of fault.

On such an implementaion the call (new int[10]) will need to allocate
11 int's just to make sure the one-passed-the-end rule is valid.

All implemetations need to avoid allocating the top of memory as
the last element of an array, as otherwise the requirment:

some_type array[N];
assert( (array + N) > (array + 0) );

i.e. the one-passed-the-end rule, will fail.
The point I'm trying to make is that undefined behaviour has
a plus side, the language is effeciently portable to a greater
number of platforms becuase of it.

For example, if the language allowed arbitary additions and
subtractions from pointers then platforms with checked pointer
registers would need to store and do all there arithmatic in
non-pointer registers, and then only load these values into the
pointer registers when dereferencing. This is against the
"Don't pay for what you don't use", "Spirit of C" that C++ inherited.
presumably thats why:
std::vector<int> v;
std::vector<int>::iterator i = v.begin();
Undefined Behaviour starts here:
i--;
All bets are now off.
i++;

Isn't guaranteed to point to *v.begin()?


Its worse than that, there is nolonger anything gauranteed.

undefined-behaviour,-it-really-does-what-it-says-on-the-tin-ly yr's Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 28 '05 #8

P: n/a
Rob Williscroft wrote:
There are implementations where you have ((p + n) - n) == p, for
any non-void pointer p and any int n. There are other implementations
where a pointer (in a register) that doesn't actually point to valid
memory causes some kind of fault. <SNIP> The point I'm trying to make is that undefined behaviour has
a plus side, the language is effeciently portable to a greater
number of platforms becuase of it.

For example, if the language allowed arbitary additions and
subtractions from pointers then platforms with checked pointer
registers would need to store and do all there arithmatic in
non-pointer registers, and then only load these values into the
pointer registers when dereferencing. This is against the
"Don't pay for what you don't use", "Spirit of C" that C++ inherited.


Ahh yes, of course.

I wasn' thinking in terms of platforms that might do that.

Very interesting, thanks.

P.S., sorry for the delay in replying, news server started denying me access for no apparent reason. It's just slow now.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 30 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.