views:

68

answers:

3

I have been looking at this piece of code, and it is not doing what I expect.

I have 3 globals.

int x, y, *pointer, z;

Inside of main I declare them.

x = 10;

y = 25;

pointer = &x;

now at this point

&x is 0x004A144  
&y is 0x004A138  

pointer is pointing to 0x004A144

Now when I increment:

y = *++pointer;

it points to 0x004A148, this is the address y should be at shouldn't it?

The idea is that incrementing the pointer to 'x' should increment it to point
at y, but it doesn't seem to want to declare them in in order like I expect.
If this a VS2005 / 2008 problem? Or maybe an Express problem?
This isn't really homework, as I have done it a couple of years ago but I was revising on my pointer stuff and I tried this again. But this time I am getting unexpected results. Does anyone have opinions on this?

*UPDATE
sorry should be more clear, 'thought' on declaration 'y' should be at 148, and that incrementing the pointer pointing to x should increment 'pointer' to 148 (which it does), but that isn't where y is. Why isn't y declaring where it should be.

+3  A: 

it points to 0x004A148, this is the address y should be at shouldn't it?

No. Address of y is still 0x...138. The operation y = *ptr copies the content pointed by ptr to y. No addresses are changed.

(Also, the address of x is still 144, because the ++ only affects pointer which only happens to have a value of 144 at initialization.)

Graphically, at initialization,

 138 (y): 25
 13c      -1
 140      -2
 144 (x): 10  <- pointer
 148      -3

After the ++pointer,

 138 (y): 25
 13c      -1
 140      -2
 144 (x): 10
 148      -3  <- pointer

Then you dereference (*) it:

 138 (y): 25
 13c      -1
 140      -2
 144 (x): 10
 148      -3  <- pointer (*pointer = -3)

and then copy this value into y (y = ...):

 138 (y): -3  <====== copy ========.
 13c      -1                        \
 140      -2                         |
 144 (x): 10                         |
 148      -3  <- pointer (*pointer = -3)

Now &x is still 144, &y is still 138, and pointer is 148, although the value y containing is changed from 25 to some unknown value (-3).

KennyTM
sorry should be more clear, 'thought' on declaration it hsoudl be at 148, and that incrementing the pointer pointing to x should increment it to 148 (whichh it does), but that isn't where y is. WHy isn't y declaring where it should be.
Craig
+7  A: 

It is really a problem with the whole idea. You can't meaningfully use a pointer to "jump" from one variable to another by incrementing and decrementing it. It is a weird, ugly and meaningless hack, for which the language gives you no guarantees whatsoever.

Pointer arithmetic in C/C++ is only defined within an array. So, if you want something like that, instead of x and y declare an array of 2 ints

int xy[2] = { 10, 25 };

initialize the pointer

int *pointer = &xy[0];

and then you can jump between xy[0] and xy[1] as much as you want by incrementing and decrementing your pointer.

AndreyT
+4  A: 

No. The compiler is free to order your varibles x, y, pointer and z in any way that it likes. ++pointer is not guaranteed to end up pointing to y, and in my experience is unlikely to in practice. laying out variables in an order different from their declaration seems to be quite common.

dereferencing ++pointer is undefined behavior.

If you need x and y to be sequential in memory, then you should declare an array of 2 ints instead of separate variables.

If your compiler supports some sort of #pragma pack to control structure packing, then I would suggest that you convert your loose global variables to a struct to guarantee ordering.

John Knoeller
every other time i have written this (and seen it written) it works as it should, i am aware these methods shoudl never be used, but i am wondering why it is doing this on this implementation only. Surely it can't have been luck all those other times.
Craig
@Craig: nope, pure luck. I even saw the VMS compiler reorder things 20 years ago on occasion.
John Knoeller
@Craig: pure coincidence. If you want to treat variables as being in an array, make them into an array. Or use a structure, or a union of a structure and an array. What you are doing is completely undefined. Compilers can - and do - reorder variables to reduce the risk of buffer overflow trampling things, for example. If you want to be tied to one version of one compiler on one platform, you can investigate what your compiler does. But don't do it in portable code - it won't work the same everywhere.
Jonathan Leffler
i know i would never do this in a real program :P It was just a test run. Only the last times i have run this and other people i know have run it the variable were sequential. But alas i can't rely on it.
Craig