My guess - and thats all what it is, I'm no expert, but programmed some assembler before -
It's somehow random but reproducible - more precisely I think its because the way a CPU stores stuff in it's registers. As far as I know a variable declared does not always need to have a memory address (if it fits the registers). Once you created a second pointer ( by << &x) somehow your variables a, b were pushed to memory. A proof for this theory might be that the memory addresses of a, b, c are reversed! So in your sec example your pointer *x just points to some random value @ &c+4 now in your first example thats the exact position where b is pushed to and you get some defined output!
random in this case means: don't use such undefined behavior! Who knows where the compiler decides to store it's data? So x++ just points to randomness!
It is possibly to do with debug settings. Have you run both pieces of code with the same settings?
In release mode you may expect that the memory would be laid out something like this:
+---+---+---+---+---+---+---+---+---+---+---+---+
| x | c | b | a |
+---+-|-+---+---+---+---+---+---+---+---+---+---+
| ^
+-------+
When you increment x by one int [1] you would expect the following
+---+---+---+---+---+---+---+---+---+---+---+---+
| x | c | b | a |
+---+-|-+---+---+---+---+---+---+---+---+---+---+
| ^
+-------------------+
Now in debugging the memory is likely to have some 'padding' between variables to aid debugging, so may look like this:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| x | pad | c | pad | b | pad | a |
+---+-|-+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| ^
+---------------+
but now when you increment the point by an int (3 bytes) it points to the padding not the next int.
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| x | pad | c | pad | b | pad | a |
+---+-|-+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| ^
+---------------------------+
Edit:
There is also no guarantee that the variables will be placed next to each other in memory anyway.
_______________________
[1] this fictional view has a 3 byte int.
Address of a : 0036FBA4
Address of b : 0036FBA0 (4 byte from previous address)
Address of c : 0036FB9C (4 byte from previous address)
Address of x : 0036FB98 (4 byte from previous address)
x = &c
x points to address : 0036FB9C That has the value 3
x++
x points to address : 0036FBA0 That has the value 2
2
debug mode output:
Address of a : 0030FD14
Address of b : 0030FD08 (12 byte from previous address)
Address of c : 0030FCFC (12 byte from previous address)
Address of x : 0030FCF0 (12 byte from previous address)
x = &c
x points to address : 0030FCFC That has the value 3
x++
x points to address : 0030FD00 That has the value -858993460
-858993460
@onur: I want to increase the pointer, not the value. My aim was to point after this operation on memory slot of variable b. So the first behavior is the aimed behavior.
@CodeMonkey: I compiled this code with MinGw. Both programms with the same settings. I also watched the address in both programms. In all cases it is the address of variable b, so &b == x is true.
@ZED0815: In both programms the variables have correct addresses, the condition &b == x is in both cases true. I'm not sure, but I think in both case the CPU should store this variables immediately to the memory. But I never programmed assembler. Such behaviour would be dangerous.
Pointer arithmetic is a dangerous thing and except rare cases when dealing directly with hardware (e.g. writing a device driver that need to send some data to the given address) there is no use for it in application programming.
Pointer arithmetic is a dangerous thing and except rare cases when dealing directly with hardware (e.g. writing a device driver that need to send some data to the given address) there is no use for it in application programming.
Ah, I think I see the problem here. Firstly, "Pointer arithmetic" is not used when sending data to a given address. That is simply manually setting a pointer value, for example like this:
somePointer = (int*)0xFFEE1000; This is not pointer arithmetic.
The second issue here is that our chum has decided that because he finds little use for something, it's useless. I see this a lot; it's generally born of very narrow experience. It's right up there with comments like "Nobody codes in C anymore" and "There's no need for low-level languages because processors are fast these days".
I expect to be reading this sort of thing forever :)
Any program which uses an array will make use of pointer arithmetic.
Examples:
1 2 3
int x[] = {2,4,6,8,10};
int y = x[3];// pointer arithmetic is used here. Dereference is implicit with this "array notation".
y = *(x+2);// here y=6. This pointer notation makes the pointer arithmetic being done obvious.
Try writing a sort routine without using pointer arithmetic!
Regarding the original example: Is it safe to assume that several int variables will be assigned to adjacent memory addresses? I thought that this is far from guaranteed .
Until today I has thought variables which are declared in succession will be assigned to adjacent memory. I thought a variable will push to stack at the moment of declaration. So their addresses should be successive. But now I'm uncertain.
Actually I was told a few days ago when asking a related question that declaring three different variables and assuming them to be in a row in memory is dangerous business!!!
I know such ussage of pointer arithmetic is very dangerous and nobody should do that (excepted handling arrays). But I'm still suprised about this different behaviour of this nearly equal code. Sorry, but that's why C++ is not my favourite language for programming user programms.
Sorry, but that's why C++ is not my favourite language for programming user programms.
The only way to have such consistency is to have guarantees about the hardware and the operating system's use of the hardware, or to abstract that away with some kind of intermediate layer. That's an enormous additional burden with the associated costs.