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

beginner's question on pointer arithmetic

P: n/a
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 ?

Mar 12 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a
su**************@yahoo.com, 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.
Mar 12 '07 #2

P: n/a
On Mar 11, 8:43 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
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. <OTAlso, 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 '07 #3

P: n/a
su**************@yahoo.com, 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.

Mar 12 '07 #4

P: n/a
"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" <bluuj...@gmail.comwrote:
On Mar 11, 8:43 pm, "subramanian10...@yahoo.com, India"

<subramanian10...@yahoo.comwrote:
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. <OTAlso, 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 '07 #5

P: n/a
On Mar 11, 9:47 pm, filehelloma...@gmail.com 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!

Mar 12 '07 #6

P: n/a
bluejack wrote:
On Mar 11, 8:43 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
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. <OTAlso, 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

Mar 12 '07 #7

P: n/a
On Mar 12, 2:21 am, "Nick Keighley" <nick_keighley_nos...@hotmail.com>
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

Mar 12 '07 #8

P: n/a
bluejack wrote:
"Nick Keighley" <nick_keighley_nos...@hotmail.comwrote:
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.)

Mar 12 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.