I'd like to know what is happening internally and its relation to values displayed.
The code is:
# include <iostream>
int main(){
using namespace std;
const int a = 10;
int* p = &a; //When compiling it generates warning "initialization from int* to
//const int* discard const -- but no error is generated
cout << &a <<"\t" << p <<endl; //output: 0x246ff08 0x246ff08 (same values)
cout << a << "\t" << *p << endl; //output: 10 10
//Now..
*p = 11;
cout << &a <<"\t" << p <<endl; //output: 0x246ff08 0x246ff08 (essentially,
//same values and same as above, but..)
cout << a << "\t" << *p << endl; //output: 10 11
return 0;
}
QUESTION: If p = address-of-a, how come a=10, but *p = (goto address of a and read value in the memory location) = 11?
cout << a << "\t" << *p << endl; //output: 10 11
You lied to the compiler and it got its revenge.
With:
const int a = 10;
you promised you'll never modify a object.
You promised not to modify a, and the compiler believed you. So it decided to optimise away the reading of a, because it trusted you. You broke your promise.
Having said that, a real C++ compiler won't compile your code because int* p = &a is illegal. So perhaps you are lying to us as well. Or perhaps you need to get a real C++ compiler.
Just like Ouah said compiler has taken its revenge
but I disagree with you that it doesn't give any error
const int a = 10;
int* p = &a;
You cannot assign constant to a non constant pointer.
In C, this is undefined behavior. In C++, this won't compile. It's been repeated by David Heffernan multiple times but it is worth repeating. Here is the error you should get on a modern compiler:
main.cpp:7:10: error: cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'
int* p = &a; //When compiling it generates warning "initialization from int* to
Related
int main()
{
int x;
x = int(&x);
int* q;
q = &x;
int* p;
p = (int*)&x;
int* w;
w = (int*)x;
cout << *p << endl << x << endl << *q << endl << *w << endl << p << endl << q << endl << w << endl << &x;
return 0;
}
OUTPUT:
5762632
5762632
5762632
5762632
0057EE48
0057EE48
0057EE48
0057EE48
Is this step x = int(&x) valid ? Is there anything conceptually wrong about this?
How to visualize/interpret what happens when we write p = (int*)&x and w = (int*)x?
Also note that this program executes only when step 1 is written. If x does not contain its own address, then the program will show an error.
Is this step x = int(&x) valid ?
Is there anything conceptually wrong about this?
The statement may be valid and could provoke undefined behavior. All depends on the platform.
On many of the platforms I've worked with, the addresses were never signed. They were always unsigned because the sign bit was needed to represent the full range of addresses. In other words, I suggest:
unsigned int x = (unsigned int) &x;
Again it's about the sign bit and how addresses are represented.
How to visualize/interpret what happens when we write p = (int*)&x and w = (int*)x?
If you want to print an address, I suggest you use the pointer format:
cout << ((void *) &x) << endl;
or
printf("%p\n", &x);
I recommend using a debugger rather than printing out addresses. The debugger allows you to examine the values in a pointer. But there are times when printing out information is a better method (like when working with multiple tasks or multiple processors).
I have the following code:
#include <iostream>
using namespace std;
int main ()
{
int myvar = 5;
int * p;
cout << "Hello2" << endl;
*p = myvar;
cout << "Hello" << endl;
cout << p << endl;
//cout << &myvar << endl;
}
I know I am not doing the right thing by not initializing the pointer. I was just playing with pointers and noticed this. The issue is when I comment out the last line, the program executes normally. But as soon as I uncomment the line, I get a segmentation fault. I don't know why printing address of myvar is causing this? Has myvar been modified in any way because of pointer dereferencing? I am using C++11.
int* p;
*p = myvar;
You are creating an uninitialized pointer and then derferencing that pointer. This has undefined behavior because p has to point to something for it to be derferenced correctly. Therefore your program's behavior can't be reasoned with.
Segmentation Fault occurs when trying to access a virtual memory address that has no read permissions.
In your case, the local variable p holds uninitialized garbage from the stack.
you are dereferencing a memory address that might not be readable(e.g no read permissions, hence the segmentation fault when trying to access it).
I'm not entirely sure the purpose of your snippet, but the following code will work, and perhaps it will help:
int myvar = 5;
int *p = nullptr;
p = &myvar;
cout << myvar << endl;
cout << &myvar << endl;
cout << p << endl;
cout << *p << endl;
(Note: I used two lines for setting 'p' because that is how you did it in your snippet. You could easily just use: int *p = &myvar; )
Anyway, there are scope issues here as p will only be valid as long as myvar is in scope; however, this does illustrate the basics of pointers. myvar and *p will return the same value (the value being pointed to), and &myvar and p will return the same value (the location of value in memory.)
basic syntax of pointers: *ptr= &a
here &a will return the memory address of variable a and *ptr will store value of variable a
I want to ask, is it possible to make a pointer return a value from a given memory address? if yes what's the syntax
Yes, you can construct a pointer that refers to some arbitrary address in memory, by initialising the pointer with the address directly, instead of with an expression like &a:
int* ptr = (int*)0x1234ABCD; // hex for convenience
std::cout << *ptr;
Be careful, though, as it is rare that you know such a memory address exactly.
The cast (int*) is required as no implicit conversion exists between int and int*.
Yes. Use the dereference operator *.
For example;
int * a = new int;
int * b = new int;
*a = 5;
// Now a points to a memory location where the number 5 is stored.
b = a; //b now points to the same memory location.
cout << *b << endl; ///prints 5.
cout << a << " " << b << endl; //prints the same address.
int * c = new int;
c = *a;
// Now c points to another memory location than a, but the value is the same.
cout << *c << endl; ///prints 5.
cout << a << " " << c << endl; //prints different addresses.
Why does the following code print 0? i.e. why does variable a is located right after variable d, even though pointer variable c is being declared between them?
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = &d - c;
int &f = e;
e ++;
cout << e << " " << endl;
return 0;
}
Working backwards:
e ++;
cout << e << " " << endl;
If this prints 0, then the value of e before executing this code must have been -1.
int e = &d - c;
So the result of the above address subtraction must have been -1.
unsigned int a /* = whatever, the value of a doesn't matter */;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d /* = whatever, the value of d doesn't matter */;
b is a reference to a, so &b is equivalent to &a.
So &d - c is equivalent to &d - &a, and that subtraction yields -1.
Conclusion: the address of d is sizeof (unsigned int) bytes after the address of a. (Pointer subtraction is scaled by the size of the pointed-to type.)
Probably.
In fact, the behavior of subtracting pointers to two independently defined objects is undefined. The standard says literally nothing about what it should do.
In practice, a compiler will probably generate the simplest possible code for a pointer subtraction, and that simple code will probably treat unrelated pointers as if they were comparable, even though the language doesn't say they are.
It's likely, given your program's output, that b and d happen to be allocated next to each other. Nothing says that declared variables have to be allocated in the order in which you declare them. If you want objects to be allocated in memory in a define order, put them into a struct or make them elements of an array.
It's also likely that the same program will yield different results if you run it on a different system, or on the same system with a different compiler, or on the same system with the same compiler with different compiler options. In principle, it could even behave differently with everything the same but during a different phase of the moon.
And a compiler is permitted to assume that your code's behavior is well defined, and perform transformations that are valid only given that assumption. In effect, by subtracting two unrelated pointers, you have promised the compiler that they both point to elements of the same array object or just past the end of it (where a single object is treated as a 1-element array) (or that both are null pointers; that's one difference between C and C++). You have lied to the compiler, which means it is under no further obligation to you.
Don't do that.
Unless you explicitly place objects using your own memory management system, their relative positions in memory will be compiler- and system-dependent.
your line int e = &d - c; is substracting 2 unsigned int *.
In memory, &d is 8 bytes farther then c (it depend on your system, but we suppose that an int is 4 bytes). Effectively, you construct your stack in this way :
unsigned int a = 100; // &a is 0x0
unsigned int &b = a; // &b is 0x0 (it's just an alias)
unsigned int *c = &b; // &c is 0x4
unsigned int d = (unsigned int)(c); // &d is 0x8
An unsigned int use 4 bytes in memory.
So, when your are doing &d - c, it must return 2, because your are using pointer arithmetics with unsigned int* (4*2=8);
You can try with int e = (short*)&d - (short*)c result should be 4 because short size is 2 (2*4=8).
You can try with int e = (char*)&d - (char*)c result should be 8 because char size is 1 (1*8=8).
Try to print your variables and addresses to understand :
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = (short*)&d - (short*)c;
//int &f = e;
//e ++;
cout << "&a: " << (unsigned int)&a << endl;
cout << "&b: " << (unsigned int)&b << endl;
cout << "&c: " << (unsigned int)&c << endl;
cout << "&d: " << (unsigned int)&d << endl;
cout << endl;
cout << " a: " << a << endl;
cout << " b: " << b << endl;
cout << " c: " << (unsigned int)c << endl;
cout << " d: " << d << endl;
cout << endl;
cout << " e: " << e << endl;
return 0;
}
Here, with int e = (short*)&d - (short*)c;, result is :
&a: 3220197356
&b: 3220197356
&c: 3220197360
&d: 3220197364
a: 100
b: 100
c: 3220197356
d: 3220197356
e: 4
const int a = 1;
int *p = const_cast<int*>(&a);
*p = 2;
cout << “value a=”<< a << endl;
cout << “value *p=” <<*p << endl;
cout << “address a=” <<&a << endl;
cout << “address p=” <<p << endl;
output:
value a=1
value *p=2
address a=0xbff1d48c
address p=0xbff1d48c
WHY???
why same addr ,diff value?
confused.
thank you!
In C++ language it is illegal to attempt to modify constant objects. Such an attempt results in undefined behavior.
In your program the *p = 2 assignment attempts to modify a constant object a. The behavior is undefined. The weird output you observe is exactly that: undefined behavior.
There's no meaningful explanation for undefined behavior.
(Your compiler probably translated the cout << a; statement into cout << 1;, since the value of a cannot legally change. So, regardless of what you do to your a, 1 will always be printed.)
In addition to AndreyT, you might be wondering that if editing a constant gives undefined behavior then why do we need const_cast<> ? The const_cast<> is meant for getting write privilege for the values which are not write protected by birth. Just try below changes and it should give proper behavior:
int b = 1; // 'b' is modifiable
const int a = b;
...