Reputation: 76
#include <iostream>
using namespace std;
int main()
{
int *pn;
char *pc;
char c = 0x65;
pn = (int *)&c;
int n = *pn;
*pn = 0x12345678;
cout << "*pn: " << hex << *pn << dec << endl;
cout << "n: " << hex << n << dec << endl;
return 0;
}
The result of this program execution is:
*pn: 12345678
n: 123456
env: I use Windows 10 and Clion to write program.
More puzzled:
1.this sentence int n = * pn;
means that the value of n
is * pn
, and the value of * pn
is 0x65
, that is, the value of n
is 0x65
. It should be unchanged after that, why do * pn = 0x12345678;
After that, the value of n
becomes 0x123456
?
2.when run int n = *pn;
, the *pn
value become dec 25957, which hex 0x6565, how does this happend? you can see this in picture 3!
I hope that the experts can answer their doubts, thank you here!
the debug picture is:
1
2
3
4
Upvotes: 0
Views: 196
Reputation: 57698
For the sake of argument, let's say that c
occupies one byte in memory. Also, let's say that an int
occupies 4 bytes in memory.
The expression int * pn = (int *) &c;
makes a pointer to a 4 byte memory point to a one byte memory. No problems so far (pointers can point to anywhere).
The statement: *pn = 0x12345678;
assigns a 4 byte value to a one byte memory location (remember that c
is only one byte in memory).
+---+
c: | |
+---+
+---+---+---+---+
pn-> | | | | |
+---+---+---+---+
The int
requires more room in memory than you have allocated.
Changing a pointer's type does not allocate more memory.
Edit 1: Possible overwrite
One possible scenario is overwriting memory.
100 101 102 103
+-----+-----+-----+-----+
c: | 65 | | | |
pn-> | | | | |
+-----+-----+-----+-----+
After *pn = 0x12345678;
:
100 101 102 103
+-----+-----+-----+-----+
c: | 12 | 34 | 56 | 78 |
pn-> | | | | |
+-----+-----+-----+-----+
If overwriting doesn't cause any exceptions, you have no idea what variables are located at addresses 101, 102 or 103. So you may be overwriting other variables.
(The above diagram assumes Big Endian layout).
There are other scenarios (such as the variable c
is allocated at the end of memory), thus you will be writing past the end of memory.
The behavior is undefined.
Edit 2: Reading - undefined behavior
In general, memory contains random values (values from other programs, values that are not initialized).
Given memory with random values (after initializing c
variable):
100 101 102 103
+-----+-----+-----+-----+
c: | 65 | ?F0 | ?0D | ?CD |
pn-> | | | | |
+-----+-----+-----+-----+
Dereferencing the pn
pointer (as a 4-byte) quantity results in 0x65F00DCD (Big Endian). Dereferencing in Little Endian Platforms: 0xCD0DF065. The '?'
represents an uninitialized value.
This is only one possible scenario. If c
is located at the last addressable memory location, your program may generate a SEGFAULT for access memory outside the boundary.
Reading multiple times
Many possible scenarios. Another scenario is that the same location is read multiple times. So in the above diagrams, dereferencing pn
(a.k.a. *pn
) could result in the value 0x65656565
.
Upvotes: 2
Reputation: 238351
char c = 0x65; pn = (int *)&c; int n = *pn;
You reinterpret char*
as int*
. When you attempt to access a non-existing int
through the reinterpreted (and potentially misaligned) pointer, the behaviour of the program is undefined.
but it is overwritten. Why is this happening?
It happens because behaviour of the program is undefined.
the *pn value become dec 25957, which hex 0x6565, how does this happend?
It happens because behaviour of the program is undefined.
Upvotes: 3
Reputation: 36389
&c
is a pointer to a single byte of memory, by casting it to int*
you are changing it to a pointer to (usually) 4 bytes of memory however there is still only a single byte of memory in the c
variable. Any change performed through the pn
pointer will attempt to write 4 bytes of memory to c
, this is undefined behaviour.
What is likely happening is that all of your variables are laid out next to each other on the stack so when you write out of the bounds of c
the writes overwrite one or more of the adjacent variables. You can't rely on this being the exact behaviour though as it is undefined.
Upvotes: 4