0

I am an expert C# programmer, but I am very new to C++. I get the basic idea of pointers just fine, but I was playing around. You can get the actual integer value of a pointer by casting it as an int:

int i = 5;
int* iptr = &i;
int ptrValue = (int)iptr;

Which makes sense; it's a memory address. But I can move to the next pointer, and cast it as an int:

int i = 5;
int* iptr = &i;
int ptrValue = (int)iptr;
int* jptr = (int*)((int)iptr + 1);
int j = (int)*iptr;

and I get a seemingly random number (although this is not a good PSRG). What is this number? Is it another number used by the same process? Is it possibly from a different process? Is this bad practice, or disallowed? And if not, is there a use for this? It's kind of cool.

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • 1
    Note that when you cast a pointer to an int and then add 1, this will produce a different value in memory than if you add 1 to it as a pointer. When you add 1 to an `int *`, the computer adds `sizeof(int)` to the value in memory. When you cast it to an `int` and then add 1, the computer just adds 1. (Or at least, this is what *usually* happens. In the presence of undefined behavior, the computer is free to do whatever, and even when behavior is defined, the computer only needs to do something that produces the same visible results as the program you wrote.) – user2357112 Dec 23 '13 at 04:03

7 Answers7

6

What is this number? Is it another number used by the same process? Is it possibly from a different process?

You cannot generally cast pointers to integers and back and expect them to be dereferencable. Integers are numbers. Pointers are pointers. They are totally different abstractions and are not compatible.

If integers are not large enough to be able to store the internal representation of pointers (which is likely the case; integers are usually 32 bits long and pointers are usually 64 bits long), or if you modify the integer before casting it back to a pointer, your program exhibits undefined behaviour and as such anything can happen.

See C++: Is it safe to cast pointer to int and later back to pointer again?

Is this bad practice, or disallowed?

Disallowed? Nah.
Bad practice? Terrible practice.

Community
  • 1
  • 1
0

You move beyond i pointer by 4 or 8 bytes and print out the number, which might be another number stored in your program space. The value is unknown and this is Undefined Behavior. Also there is a good chance that you might get an error (that means your program can blow up) [Ever heard of SIGSEGV? The Segmentation violation problem]

Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
0
int i = 5;
int* iptr = &i;
int ptrValue = (int)iptr;
int* jptr = (int*)((int)iptr + 1);
int j = (int)*iptr;
  1. You can cast int to pointer and back again, and it will give you same value
  2. Is it possibly from a different process? no it's not, and you can't access memory of other process except using readProcessMemmory and writeProcessMemory under win32 api.
  3. You get other number because you add 1 to the pointer, try to subtract 1 and you will same value.
phuclv
  • 37,963
  • 15
  • 156
  • 475
SRedouane
  • 498
  • 5
  • 10
0

When you define an integer by

int i = 5;

it means you allocate a space in your thread stack, and initialize it as 5. Then you get a pointer to this memory, which is actually a position in you current thread stack

When you increase your pointer by 1, it means you point to the next location in your thread stack, and you parse it again as an integer,

int* jptr = (int*)((int)iptr + 1);
int j = (int)*jptr;

Then you will get an integer from you thread stack which is close to where you defined your int i.

Of course this is not suggested to do, unless you want to become an hacker and want to exploit stack overflow (here it means what it is, not the site name, ha!)

phuclv
  • 37,963
  • 15
  • 156
  • 475
Daniel King
  • 407
  • 4
  • 11
  • You can exploit stack overflows with this? I thought stack overflow meant game over for my program. – Alexander Kvenvolden Dec 23 '13 at 03:33
  • If you use memcpy to copy a huge buffer to jptr or iptr, you can definitely make the stack a mess, but if you are an expert, you can use a buffer which can just modified the return address to point to your function, where you can do your "BAD" things, But don't do it! – Daniel King Dec 23 '13 at 03:39
0

Using a pointer to point to a random address is very dangerous. You must not point to an address unless you know what you're doing. You could overwrite its content or you may try to modify a constant in read-only memory which leads to an undefined behaviour...

This for example when you want to retrieve the elements of an array. But cannot cast a pointer to integer. You just point to the start of the array and increase your pointer by 1 to get the next element.

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;

printf("%d", *p); // this will print 1

p++; // pointer arithmetics

printf("%d", *p); // this will print 2
phuclv
  • 37,963
  • 15
  • 156
  • 475
rullof
  • 7,124
  • 6
  • 27
  • 36
0

You are discovering that random places in memory contain "unknown" data. Not only that, but you may find yourself pointing to memory that your process does not have "rights" to so that even the act of reading the contents of an address can cause a segmentation fault.

In general is you allocate some memory to a pointer (for example with malloc) you may take a look at these locations (which may have random data "from the last time" in them) and modify them. But data that does not belong explicitly to a pointer's block of memory can behave all kings of undefined behavior.

Incidentally if you want to look at the "next" location just to

NextValue = *(iptr + 1);

Don't do any casting - pointer arithmetic knows (in your case) exactly what the above means : " the contents of the next I refer location".

Floris
  • 45,857
  • 6
  • 70
  • 122
0

It's not "random". It just means that there are some data on the next address

Reading a 32-bit word from an address A will copy the 4 bytes at [A], [A+1], [A+2], [A+3] into a register. But if you dereference an int at [A+1] then the CPU will load the bytes from [A+1] to [A+4]. Since the value of [A+4] is unknown it may make you think that the number is "random"

Anyway this is EXTREMELY dangerous since

That's why the C and C++ standard state that reading memory outside an array invokes undefined behavior. See

phuclv
  • 37,963
  • 15
  • 156
  • 475