beginner's question on pointer arithmetic

S

subramanian100in

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 ?
 
R

Richard Heathfield

(e-mail address removed), 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.
 
B

bluejack

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>
 
S

santosh

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.
 
F

filehellomarch

"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.
 
B

bluejack

"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!
 
N

Nick Keighley

bluejack said:
On Mar 11, 8:43 pm, "(e-mail address removed), India"


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?
 
B

bluejack

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.
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
 
S

santosh

[ ... ]
[ ... ]
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.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top