# beginner's question on pointer arithmetic

Discussion in 'C Programming' started by subramanian100in@yahoo.com, India, Mar 12, 2007.

1. ### , IndiaGuest

Supoose we have,

int x;

int *p = &x;

int *q;

q = p + 1;

Is calculating p+1 correct ? My uderstanding is that, only for arrays,
we can take the address of one element past the end of array. In this
case, p + 1 should invoke undefined bahaviour even if it produces
sizeof(int) bytes beyond the location of x.

Am I wrong ?

, India, Mar 12, 2007

2. ### Richard HeathfieldGuest

, India said:

> Supoose we have,
>
> int x;
>
> int *p = &x;
>
> int *q;
>
> q = p + 1;
>
> Is calculating p+1 correct ?

You can calculate it, but that's all. You can't deref it.

> My uderstanding is that, only for arrays,
> we can take the address of one element past the end of array.

For this purpose, an object can be considered equivalent to an array of
one object.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.

Richard Heathfield, Mar 12, 2007

3. ### bluejackGuest

On Mar 11, 8:43 pm, ", India"
<> wrote:
> Supoose we have,
>
> int x;
> int *p = &x;
> int *q;
> q = p + 1;
>
> Is calculating p+1 correct ? My uderstanding is that, only for arrays,
> we can take the address of one element past the end of array. In this
> case, p + 1 should invoke undefined bahaviour even if it produces
> sizeof(int) bytes beyond the location of x.

In practical terms, q is now pointing to memory one int* beyond p; the
contents of that memory are entirely unknown to you, and attempting to
do anything with that memory is where you'll run into trouble.

(Since you never assigned anything to x or to *p, attempting to do
access the contents of x, *p, or *q are also going to run into
trouble.)

I'm not a standards guru, so I can't tell you whether this trouble is
"undefined behavior" or not, but *writing* to memory that has never
been allocated (also called "smashing memory") is the source of the
nastiest bugs to track down, and probably the number one reason for
avoiding pointer arithmetic. (Imagine the memory address you have now
pointed q at is the start of a string that is used somewhere else in
the code entirely; setting that to '0' terminates the string; while
you're trying to figure out why that string disappears, you might
never think to look in *this* block of code. Nasty stuff.)

Reading from uninitialized memory can also be confusing, as *most* of
the time, that uninitialized value might be 0, like you expect, but
then occasionally it's not, which also makes for some headaches. Bugs
that can't reliably be reproduced are never fun. <OT> Also, some
compilers will 0 out uninitialized automatic variables on low levels
of optimization, but not on higher levels; so if you compile in a
debug mode during development, and then add optimization when you're
Again, not fun.</OT>

bluejack, Mar 12, 2007
4. ### santoshGuest

, India wrote:
> Supoose we have,
>
> int x;
> int *p = &x;
> int *q;
> q = p + 1;
>
> Is calculating p+1 correct ?

Yes.

> My uderstanding is that, only for arrays,
> we can take the address of one element past the end of array.

An object can be considered as an array of one element.

> In this
> case, p + 1 should invoke undefined bahaviour even if it produces
> sizeof(int) bytes beyond the location of x.

No. Pointing to one past the object is okay, but deferencing it will
invoke undefined behaviour.

santosh, Mar 12, 2007
5. ### Guest

"In practical terms, q is now pointing to memory one int* beyond p;"

In fact, q is now pointing to memory one int (not int *)beyond p.

On 3ÔÂ12ÈÕ, ÏÂÎç12Ê±16·Ö, "bluejack" <> wrote:
> On Mar 11, 8:43 pm, ", India"
>
> <> wrote:
> > Supoose we have,

>
> > int x;
> > int *p = &x;
> > int *q;
> > q = p + 1;

>
> > Is calculating p+1 correct ? My uderstanding is that, only for arrays,
> > we can take the address of one element past the end of array. In this
> > case, p + 1 should invoke undefined bahaviour even if it produces
> > sizeof(int) bytes beyond the location of x.

>
> In practical terms, q is now pointing to memory one int* beyond p; the
> contents of that memory are entirely unknown to you, and attempting to
> do anything with that memory is where you'll run into trouble.
>
> (Since you never assigned anything to x or to *p, attempting to do
> access the contents of x, *p, or *q are also going to run into
> trouble.)
>
> I'm not a standards guru, so I can't tell you whether this trouble is
> "undefined behavior" or not, but *writing* to memory that has never
> been allocated (also called "smashing memory") is the source of the
> nastiest bugs to track down, and probably the number one reason for
> avoiding pointer arithmetic. (Imagine the memory address you have now
> pointed q at is the start of a string that is used somewhere else in
> the code entirely; setting that to '0' terminates the string; while
> you're trying to figure out why that string disappears, you might
> never think to look in *this* block of code. Nasty stuff.)
>
> Reading from uninitialized memory can also be confusing, as *most* of
> the time, that uninitialized value might be 0, like you expect, but
> then occasionally it's not, which also makes for some headaches. Bugs
> that can't reliably be reproduced are never fun. <OT> Also, some
> compilers will 0 out uninitialized automatic variables on low levels
> of optimization, but not on higher levels; so if you compile in a
> debug mode during development, and then add optimization when you're
> ready to release your product: voila, bugs you've never seen before.
> Again, not fun.</OT>

, Mar 12, 2007
6. ### bluejackGuest

On Mar 11, 9:47 pm, wrote:
> "In practical terms, q is now pointing to memory one int* beyond p;"
>
> In fact, q is now pointing to memory one int (not int *)beyond p.

Ooops. Exactly so. Tx!

bluejack, Mar 12, 2007
7. ### Nick KeighleyGuest

bluejack wrote:
> On Mar 11, 8:43 pm, ", India"
> <> wrote:

> > Supoose we have,
> >
> > int x;
> > int *p = &x;
> > int *q;
> > q = p + 1;
> >
> > Is calculating p+1 correct ? My uderstanding is that, only for arrays,
> > we can take the address of one element past the end of array. In this
> > case, p + 1 should invoke undefined bahaviour even if it produces
> > sizeof(int) bytes beyond the location of x.

>
> In practical terms, q is now pointing to memory one int* beyond p; the
> contents of that memory are entirely unknown to you, and attempting to
> do anything with that memory is where you'll run into trouble.
>
> (Since you never assigned anything to x or to *p, attempting to do
> access the contents of x, *p, or *q are also going to run into
> trouble.)
>
> I'm not a standards guru, so I can't tell you whether this trouble is
> "undefined behavior" or not,

it is

> but *writing* to memory that has never
> been allocated (also called "smashing memory") is the source of the
> nastiest bugs to track down, and probably the number one reason for
> avoiding pointer arithmetic.

you could just try doing the pointer arithmetic correctly.

> (Imagine the memory address you have now
> pointed q at is the start of a string that is used somewhere else in
> the code entirely; setting that to '0' terminates the string; while
> you're trying to figure out why that string disappears, you might
> never think to look in *this* block of code. Nasty stuff.)
>
> Reading from uninitialized memory can also be confusing, as *most* of
> the time, that uninitialized value might be 0, like you expect,

well I wouldn't. What implementation zeros newly allocated (whatever
*that* means) memory?

> but
> then occasionally it's not, which also makes for some headaches. Bugs
> that can't reliably be reproduced are never fun. <OT> Also, some
> compilers will 0 out uninitialized automatic variables on low levels
> of optimization, but not on higher levels; so if you compile in a
> debug mode during development, and then add optimization when you're
> ready to release your product: voila, bugs you've never seen before.
> Again, not fun.</OT>

--
Nick Keighley

Nick Keighley, Mar 12, 2007
8. ### bluejackGuest

On Mar 12, 2:21 am, "Nick Keighley" <>
wrote:

> bluejack wrote:
> > but *writing* to memory that has never
> > been allocated (also called "smashing memory") is the source of the
> > nastiest bugs to track down, and probably the number one reason for
> > avoiding pointer arithmetic.

>
> you could just try doing the pointer arithmetic correctly.

Of course; but to someone who is apparently new at this, I thought I
would explain some of the hazards. No need to be snide.

> > Reading from uninitialized memory can also be confusing, as *most* of
> > the time, that uninitialized value might be 0, like you expect,

>
> well I wouldn't. What implementation zeros newly allocated (whatever
> *that* means) memory?

Of course you wouldn't. Again, I'm pointing out the hazards to someone
who hasn't been caught in them yet. I find as more students graduate
having been trained on java they actually do have these kinds of
expectations, or perhaps *intuitions* of how things work by default.

GCC zeros stack allocated variables at -O0, but not at higher levels
of optimization. Or at least it used to; this isn't something I test
regularly.

-b

bluejack, Mar 12, 2007
9. ### santoshGuest

bluejack wrote:
> "Nick Keighley" <> wrote:
> > bluejack wrote:

[ ... ]

> > > Reading from uninitialized memory can also be confusing, as *most* of
> > > the time, that uninitialized value might be 0, like you expect,

> >
> > well I wouldn't. What implementation zeros newly allocated (whatever
> > *that* means) memory?

[ ... ]

> GCC zeros stack allocated variables at -O0, but not at higher levels
> of optimization. Or at least it used to; this isn't something I test
> regularly.

Apparently not anymore, or at least, not my installation, (gcc 4.0.3
i686.)

santosh, Mar 12, 2007