Case 1
#include <iostream>
using namespace std;
int main() {
int n = 1;
// int & r = n;
int * p;
cout << &n << endl;
cout << p << endl;
return 0;
}
Output 1
0x7fffffffdc94
0
Case 2
#include <iostream>
using namespace std;
int main() {
int n = 1;
int & r = n;
int * p;
cout << &n << endl;
cout << p << endl;
return 0;
}
Output 2
0x7fffffffdc8c
0x7fffffffdd90
In Output 2, the pointer p just pointed to the address followed int n. Shouldn't an unintialized pointer point to some random places?
Why adding a reference declaration influences the address of p pointed to?
Shouldn't an unintialized pointer point to some random places?
No, an uninitialized pointer points nowhere. It has an indeterminate value. Trying to read and/or print this indeterminate pointer value as you are doing in
cout << p << endl;
has undefined behavior. That means there is no guarantee whatsoever what will happen, whether there will be output or not or whatever the output will be.
Therefore, there is no guarantee that changing any other part of the code doesn't influence the output you will get. And there is also no guarantee that the output will be consistent in any way, even between runs of the same compiled program or multiple compilations of the same code.
Practically, the most likely behavior is that the compiler will emit instructions that will simply print the value of whatever memory was reserved on the stack for the pointer. If there wasn't anything there before, it will likely result in a zero value. If there was something there before it will give you that unrelated value.
None of this is guaranteed however. The compiler can also just substitute the read of the pointer value with whatever suits it or e.g. recognize that reading the value has undefined behavior and that it may therefore remove the output statement since it can not be ever reached in a valid program.
Related
it seems like I have a fundamental problem in understanding pointers in C++. In my understanding, the following code example should print "53" in the console, but instead it prints "33".
// Example program
#include <iostream>
#include <vector>
int main()
{
std::vector<int*> v;
{
int z = 5;
v.push_back(&z);
}
{
int a = 3;
v.push_back(&a);
}
std::cout << *v[0] << *v[1] << std::endl;
}
I originally had this problem in a bigger project I'm currently working on and I recognized that if I'm doing it this way, all pointers I added previously point to the same element as the last one. But why? I thought that if i add two pointers which point to different integers, they will stay different after adding them to a vector.
This:
{
int a = 3;
v.push_back(&a);
}
Results in undefined behavior: you are storing the address of a temporary and using it later. This means anything could happen: the program could print "I'm sorry David, I can't do that."
As soon as the scope ends (with }), the lifetime of a ends, and the address it used to occupy is available to be reused. And that is what happens in your code, the same address gets reused so you end up storing the same address twice. But again, undefined behavior means anything could happen. For example, if I compile with optimization enabled on my computer it prints "33" but if I disable optimization it prints "53".
The problem was with your scoping. Remove the scopes and you get the expected behaviour:
std::vector<int *> v;
int z = 5;
v.push_back(&z);
int a = 3;
v.push_back(&a);
std::cout << *v[0] << *v[1] << std::endl;
Original code has undefined behaviour:
std::vector<int*> v;
{
int z = 5;
v.push_back(&z);
} // here z no longer exists, so you can't dereference it later via *v[0]
Here in this code, I have first described int a and assigned value 9 to it and then I declared another int b and then I have given value 3 to *(&b-1) so (&b-1) refers to &a and then I printed the value of a then it prints 9 only but when I add new line in the code(line no. 6) i.e. first printed a and then assigned value 3 to (&b-1) then it updates a to 3 and prints it. So why it's happening like this?
#include <iostream>
using namespace std;
int main() {
double a, b;
a = 9;
//cout<<&a<<" "<<a << endl ;
*(&b - 1) = 3;
cout << a << " " << &b - 1 << " ";
cout << &a;
}
so (&b-1) refers to &a
No, that's not how C++ works.
You can't "navigate" the stack frame like this, because C++ is an abstraction and does not have stack frames.
What you're doing here is pretending that b is a pointer to the second (or later) element of an array, and trying to get the value of the preceding element in that array. As we know, you do not actually have an array.
So why it's happening like this?
That's why. You lied to the compiler, and now it's freaking out.
Yes, it really does care about this kind of thing!
Your question is based on a false premise
[...] (&b-1) refers to &a [...]
Thats wrong. So when you ...
*(&b - 1) = 3;
you are dereferencing a pointer that you are not allowed to dereference. There is no double stored at (&b - 1). As this is undefined behaviour your program can do anything and thats about as much as one can say about your code ;).
This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 6 years ago.
I have these two almost identical bits of c++
#include <iostream>
using namespace std;
int main(){
int a = 0;
int b = 1;
int c = 2;
int d = 3;
int *p = &a;
cout << &c << endl;
cout << *(p+1);
}
with the output:
0x7ffd7b16998c
2
and
#include <iostream>
using namespace std;
int main(){
int a = 0;
int b = 1;
int c = 2;
int d = 3;
int *p = &a;
cout << &d << endl;
cout << *(p+1);
}
which produces the output:
0x7ffdb7ea105c
3
Why does the value of *(p+1) depend on what I output beforehand?
If I delete the line
cout << &c << endl;
completely i get the expected 1 as an output.
What on earth is happening?
What's happening is undefined behavior.
When you obtain a pointer to an int, you are allowed to use the value of that pointer alone; pointer arithmetic is meaningless.
In order for p+1 to produce an address that you can dereference, p must point to an array element other than its last element. In all other situations, reading *(p+1) is undefined.
Standards aside, the CPU must be taking that value from some place. You assume that the place must be the address of b, which is declared immediately after a. However, C++ makes no guarantees about location of local variables in memory relative to each other. It appears that the compiler reorders your variables, producing an output that you did not expect (and it's undefined anyway).
*(p+1) accesses memory after a so it's Undefined Behaviour.
Propably you intended (*p)+1 to increase a by 1?
How is it possible that the value of *p and the value of DIM are different but the have the same address in memory?
const int DIM=9;
const int *p = &DIM;
* (int *) p = 18; //like const_cast
cout<< &DIM <<" "<< p << '\n';
cout << DIM << " " << *p << '\n';
You're changing the value of a const variable, which is undefined behavior. Literally anything could happen when you do this, including your program crashing, your computer exploding, ...
If a variable is supposed to change, don't make it const. The compiler is free to optimise away accesses to const variables, so even if you found a successful way to change the value in memory, your code might not even be accessing the original memory location.
It is a compiler optimization. Given that DIM is a constant, the compiler could have substituted its known value.
The code below does what you meant to do... as mentioned in other posts, if you mean to change the value of an variable, do not define it as const
#include <stdio.h>
int main()
{
int d= 9;
int *p_d=&d;
*p_d=18;
printf("d=%d\np_d=%d\n",d,*p_d);
return 0;
}
This code prints
d=18
p_d=18
Wouldn't the highest pointer be the one which can't be incremented through pointer arithmetic?
#include <iostream>
int main()
{
// Find the largest pointer
int x = 0;
int* px = &x;
while ((px+1) != px)
++px;
std::cout << "The largest pointer is: " << px;
return 0;
}
yields
Timeout
As already mentioned, you've got an infinite loop because the condition can never be false.
That being said, what you're doing is undefined behaviour, illegal C++. Pointer arithmetic is only legal with pointers pointing to the same array (and a single object is treated as an array of one element) and right past the end of it. You can't expect a reasonable outcome of your program even if you fix the loop.
I suspect the value of std::numeric_limits<uintptr_t>::max() is the theoretical maximum value of pointer (converted to integer), but it might not be avaliable to your program. There are things such as virtual address space and segmented memory model to consider. Anyway, exact values of pointers (except for nullptr) is not something you should be concerned with. You get pointers by taking addresses of existing objects or by calling allocation functions and that's that.
N.B. I think you have a misconception that attempting to increment an integer type beyond its maximum value will just do nothing. That's incorrect - unsigned integers will wrap around to 0 and with signed integers you get undefined behaviour again (see signed integer overflow).
Hope that helps.
This will never be false and thus never quit
while ((px+1) != px)
Look at this program:
#include <iostream>
int main()
{
int *px = (int *) (~0);
std::cout << "Value: " << px;
++px;
std::cout << " Value: " << px << std::endl;
}
whose output is:
Value: 0xffffffffffffffff Value: 0x3
As you can see, when you increment a pointer that is at its maximum, it values is reseted and begins again
You might want to look for the largest pointer value that occurs before wrap-around, i.e.:
while (px+1 > px)
px++;
...which will not work, of course, without the proper casts:
while ((unsigned long long)(px + 1) > (unsigned long long)px)
px++;