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?
Related
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.
This question already has answers here:
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Closed 3 years ago.
I'm trying to learn C++, specifically how to declare and initialize variables. I wrote this code, and I don't know why the variable c is giving a value that I have not assigned it yet.
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!\n";
int a, b;
a = 1;
b = 2;
int d(4);
int result;
auto num = b;
decltype(b) c;
result = a + b - d;
cout << c;
}
The output is -2, but I didn't state c = -2 anywhere!
If you have not initialized the variable, it contains garbage value.
In C/C++, the values declared within a function represent some bytes of main memory on the cpu stack. Those bytes are usually dirty and need initialization. If you don't the values are undefined. That you're always getting '-2' is merely coincidence.
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:
Weird Behaviour with const_cast [duplicate]
(2 answers)
Closed 5 years ago.
const int *a = new int(100);
int *ptr = (int*) a;
cout << *a << endl;
*ptr = 1000;
cout << *a << endl;
const int b = 100;
int *c = (int*)&b;
*c = 200;
cout << &b << " " << b << endl;
cout << c << " " << *c << endl;
print out
While I use *ptr, I can change the const data *a. Why?
Both the address of b and *c are the same, but the data are different. Why?
While I use *ptr, I can change the const data *a. Why?
Because your program is causing undefined behavior. You lied to the compiler that b is non-const by casting const-ness away from the pointer produced by &b, but writing to that pointer on the *c = 200 line is undefined behavior.
Both the address of b and *c are the same, but the data are different. Why?
It happens for the same reason: the behavior is undefined.
As for the real-life scenario when this would happen, I would speculate that the compiler has optimized out the read of b, because you promised it that b is const. However, the compiler found a clever way of getting back at you by replacing a read of the actual b with the output of a constant that has been assigned to b originally.
This question already has answers here:
Why are references not reseatable in C++
(17 answers)
Closed 7 years ago.
According to these links: stackoverflow question and C++ FQA references cannot refer to another object/ variable well once they're initialized, but what about the below code?
// Example program in C++
#include <iostream>
using namespace std;
int main()
{
int x=10, z=12;
int &y=x;
++y;
y=z; //valid?
cout << x << ", "<< y <<", " << z << endl; // prints 12, 12, 12
return 0;
}
Below is the C code regarding pointer reseating and it seems valid, am I right?
#include <stdio.h>
int main(int argc, char *argv[])
{
int a=10, b=20;
int *ptr;
ptr = &a;
ptr = &b;
printf("%d\n",a); // prints 10
printf("%d\n",*ptr); // prints 20
return 0;
}
Can someone clear the above concept in the above two codes?
y=z; //valid?
Absolutely! However, it does not mean "y refers to z from now on". It means "set the value of z to whatever y is currently referring", which is x. Hence, y=z is another way of writing x=z.
Below is the C code regarding pointer reseating and it seems valid, am I right?
Unlike references, pointers can be re-pointed, so the re-assignment of the pointer makes it point to a different variable. Your program does not illustrate this, however, because two assignments to ptr happen without any reads of ptr in between, so only the second assignment stays.
In y=z
Its not refering to another variable its just assigning the value of z to y which is 12 and since y is reference to x, x also gets assigned value 12.
so x=y=z=12
But in pointers its valid to change the address it points to:
ptr = &a;
ptr = &b; //valid