I can't seem to find the answer on here, but I'm sorry if this is a duplicate. Here's my question: When I have two pointers to the same location, then I change the address of one (let's say pointer A), will I (by accident) be changing the address of the other pointer (pointer B)? Or will pointer B's location stay the same?
Changing the contents of a pointer (as opposed to the object being pointed to) will not affect other pointers to the same object.
Picture speaks a thousand words.
Pointers are pointing to another memory place, at the same time, they have their own memory space.
Two pointers, A and B point to the same place, yet, they are kept in separate memory locations. (Left half of the image)
If you change B, you will only change what B is pointing, A remains the same. (Right half of the image)
Pointer B's location will stay the same.
Because pointer A and pointer B are different pointer,they have different memory address.That means they are independent each other although both of them point to the same memory address.
But you should be careful when you try to change pointer A's content,this operation may cause pointer B be a wild pointer by accident!
A pointer holds the memory address of a piece of data in memory.
The value of the pointer variable is this address.
int targetA = 1;
int targetB = 2;
int *pointerA = &targetA;
int *pointerB = &targetA;
printf("%p, %p\n", pointerA, pointerB);
// => 0x7fff5c78e8f8, 0x7fff5c78e8f8
pointerB = &targetB;
printf("%p, %p\n", pointerA, pointerB);
// => 0x7fff5c78e8f8, 0x7fff5c78e8f4
By assigning a different address / location to the pointer you just change what it points to, other variables are not affeted.
You can see the output of the below code :
#include <iostream>
int main(int argc, char **argv){
int a = 3, d = 4;
int *b = &a, *c = &a;
std::cout << b << ", " << c << std::endl;
b = &d;
std::cout << b << ", " << c << std::endl;
}
The following is the output of the code :
0x7ffca3788e40, 0x7ffca3788e40
0x7ffca3788e44, 0x7ffca3788e40
Clearly, changing the address b points to, has nothing to do with the address pointed by pointer c.
But you can have a near-similar phenomena when you use references. A reference is an entity that is an alias for another object. Suppose you have
int &ref = a;
ref = 5;
Now, changing the variable ref will also bring a change in the value of variable a, equating it to 5.
Let's take a look at this code snippet.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int * myp1, * myp2;
int myvalue;
myp1 = &myvalue;
myp2 = &myvalue;
myvalue = 10;
cout << "first address is " << myp1 << '\n';
cout << "second address is " << myp2 << '\n';
Here, the outputs are the same (when I run it, I get first address is 0x759ba27bb1d8
second address is 0x759ba27bb1d8).
int myvalue2;
myp1 = &myvalue2;
myvalue2 = 20;
cout << "first address is " << myp1 << '\n';
cout << "second address is " << myp2 << '\n';
return 0;
}
Here, the addresses are different, but myp2 points to the same address as above.
And it makes sense; you have two separate things pointing to the same address. Why would changing what one thing points to change the other?
A (possibly very bad analogy) would be: consider that you and someone on the other end of the world are pointing at the sky (say, at the same point in the sky). Then, you point at the ground. Just because you pointed at the ground, doesn't mean the other guy will stop pointing at the sky.
Hope that helps.
Related
I am messing around a little with pointers. Please take a look at the following results (addresses).
1st code:
#include <iostream>
int main(){
int a = 5;
void* pointer = &a;
std::cout << a << std::endl << &a << std::endl;
std::cout << pointer << std::endl ;
std::cin.get();
}
Result:
2nd code:
#include <iostream>
int main(){
int a = 5;
void* pointer = &a;
std::cout << a << std::endl << &a << std::endl;
std::cout << &pointer << std::endl ;
std::cin.get();
}
Result:
Why does the address of the variable a change between the two codes?
In the first case, you never take the address of pointer, so pointer can be stored in a register, or even not at all. (Modern compilers are very clever, and modern machines have many registers.)
For instance, gcc 11 keeps the value in a register without optimization, and with -O2 it just inserts the address of a directly. (Assembly here, for the curious.)
In the second case, you do take the address of pointer, so it must be stored somewhere in memory.
This means that a might be stored in a different place in order to make room for it.
Also, some platforms randomize storage locations in order to make programs less hackable, so it's usually not a good idea to assume that things will have the same address in different "runs".
In the first code poiner stores the address of variable a, and by command.
std::cout<<pointer<<std::endl;
You print the address of a. That's it.
In the second code pointer also stores the address of variable a, but &pointer is the address of variable pointer. Try the following
#include <iostream>
int main(){
int a = 5;
void* pointer = &a;
void** pointer_to_pointer = &pointer;
std::cout << a << std::endl << &a << std::endl << pointer << std::endl;
std::cout << &pointer << std::endl << pointer_to_pointer;
std::cin.get();
}
The output for me is
5
0x7aba1bd92e94
0x7aba1bd92e94
0x7aba1bd92e98
0x7aba1bd92e98
It is very simple.
int a and void* pointer are two distinct variables or I better say memory locations on the stack. a holds a value like 5 in its location. pointer holds the address to a's memory location. pointer itself is stored in a different location and when you write std::cout << &pointer << std::endl; it will print the address of the pointer variable, not the contents of it which is a's address.
As a simplified example:
Consider 0x4 as the address of pointer itself and the value inside it is 0xC. This value points to a's location. In order to read the value of a(which is 5), you first have to go to 0x4 to read its content. Its content is 0xC and now you have successfully found out that a's location is 0xC. Then you have to go to 0xC and at that address, you will find the value 5.
You look at -> 0x4( content == 0xC ) -> 0xC( content == 5 ) -> done!
I am getting segmentation fault in first code but the second code is running fine, don't know how?
How can I copy a pointer and save it to another pointer?
#include <iostream>
using namespace std;
int main() {
int *p;
int *p1;
*p1=7;
p=p1;
cout<<*p<<" "<<p;
return 0;
}
#include <iostream>
using namespace std;
int main() {
int *p1;
*p1=7;
int *p=p1;
cout<<*p<<" "<<p;
return 0;
}
//7 0x7ffeea73db70
Both cases invoke undefined behaviour, in both cases you make use of uninitialized pointer p1, the fact that the second case "works" for you is a matter of sheer luck, as you can see here.
For your code to be valid you need to make it point to a valid memory address either by allocating memory manually:
int *p1 = new int; //raw pointer, (better to use smart pointers* but let's not get ahead of ourselves).
Or by assigning it the address of a valid int variable:
int i = 5;
int *p1 = &i;
How can I copy a pointer and save it to another pointer?
A pointer is essentially a variable like any other, you can copy it like you do a normal primitive variable, in fact you do just that when you do p = p1, these are two different pointers that will now contain the same value, the address of the variable they point to.
This code exemplifies this
#include <iostream>
using std::cout;
using std::endl;
int main() {
int *p1 = new int;
*p1 = 7;
int *p = p1;
cout<< "Value stored in the address p points to: " << *p << endl
<< "Value stored in the address p1 points to: " << *p1 << endl
<< "Address where p points to: " << p
<< " " << endl << "Address where p1 points to: "<< p1
<< endl << "Address of p: " << &p << endl << "Address of p1: "<< &p1;
return 0;
}
The output:
Value stored in the address p points to: 7
Value stored in the address p1 points to: 7
Address where p points to: 0x804150
Address where p1 points to: 0x804150
Address of p: 0x7ffc9447e220
Address of p1: 0x7ffc9447e228
*What is a smart pointer and when should I use one?
When you dereference an int* pointer, you promise that there is an int object at that address. C++ believes you, often without questioning. But you never wrote int a; p1=&a; or any other code that made sure p1 points to an actual int.
In fact, p1 isn't even a null pointer. The only thing you can do with p1 is to assign it a legal value. That is to say, it must appear at the left-hand side of an assignment first. It can't be used on the right hand side in int* p = p1;
I am busy learning about pointers and playing around a bit with different results.
While doing this I noticed that when I declare a variable and obtain its address, I get one value. But then when I declare a pointer that points to that variable, I get a different address for that same variable. And I also saw that this new address given to the variable was actually the address of the pointer itself(after checking). How can this be?
Just to be clear; I declared int a and then int *p to point to a. The address for a was 0x22ff2c (originally before declaring pointer), and the address for the pointer p was 0x22ff28. The new address for a after I declared the pointer was also 0x22ff28, the same as the address of the pointer itself.
I looked around on the net and here on SO to find some answers, but didn't really get what I needed. Here as some links which came close. This SO Link1 touches on the subject, but doesn't tell me what I don't already know. This other one SO Link2 seems similar to what I am asking, but it's way too advanced and makes my head spin.
A simple explanation would be appreciated as I am still very new to C++, thank you.
Code 1
int main()
{
int a = 1;
std::cout << "Address1: " << &a;
return 0;
}
output of code 1 ##
Address1: 0x22ff2c
code 2
int a = 1;
int *p;
p = &a;
std::cout << "Address1: " << p;
return 0;
output of code 2
Address1: 0x22ff28
code 3
int a = 1;
int *p;
p = &a;
std::cout << "Address1: " << p << "\n" << "Address2: " << &a;
return 0;
output of code 3
Address1: 0x22ff28
Address2: 0x22ff28
code 4
int a =1;
int *p;
p = &a;
std::cout << "Address1: " << &p;
output of code 4
Address1: 0x22ff28
Because &a == p. You are not printing the pointer's address. For that print &p instead of p. You will likely get a different address.
Try this :
#include <iostream>
int main() {
int a = 3 ;
int *p = &a ;
std::cout << &a << "\n" << p << "\n" << &p ;
return 0;
}
0x22ff28 is not address of the pointer but of the target the pointer is pointing to. Which is a. The address of the pointer is &p.
Here's part of what I think you're trying to ask: First a had address 0x22ff2c, then the program was changed to have variable p and after that a has a different address. Why?
The answer is, the compiler made different choices when building the second program than it did when build the first. After all, they're different programs.
The actual memory addresses used by two different programs (even if they are mostly similar) may be different for various reasons. They're not really comparable. (And when you get into more complex and less predictable situations, especially using dynamic allocation, then the memory addresses used by different invocations of the same program can be different.)
Now, for another part of your question:
The new address for "a" after I declared the pointer was also 0x22ff28, the same as the address of the pointer itself.
In the code you've shown, you're only ever examining the address that p contains, not the address that p itself lives at. If you try outputting &p then you'll see where it is and find that it is indeed different than &a.
I was trying to access the private data members of the class. Everything was going fine until I came upon the int*. I don’t get what it is. I think it’s something that we can use to create a new memory address.
My code :
#include <iostream>
using namespace std;
class x
{
int a, b, c, d;
public:
x()
{
a = 100;
b = 200;
c = 300;
d = 400;
}
};
int main()
{
x ob;
int *y = (int *)&ob;
cout << *y << " " << y[1] << " " << y[2] << " " << y[3] << endl;
}
Can anyone help me in understanding it?
Its a c-style cast to access the memory occupied by the struct x as a set of ints.
It takes the address of ob, casts it from 'address of' (ie a pointer to) x into a pointer to int. The compiler happily assigns this cast to y, so you can manipulate it, or in this case, print out the memory blocks as ints. As the struct happens to be a group of ints anyway, it all works even though its a bit of a hack. I guess the original coder wanted to print out all 4 ints without having to specify each one in turn by variable name. Lazy.
Try using a cast to a char* (ie 1 byte at a time) and print those out. You'll be basically printing out the raw memory occupied by the struct.
A good C++ way would be to create an operator<< function that returns each variable formatted for output like this, then write cout << ob << endl; instead.
Correction:
I messed up with the concept of pointer address and the address the pointer points to, so the following code has been modified. And now it prints out what I want, variable a, c, i, j, k, p are on the stack, and variable b,d are on the heap. Static and global variables are on another segment. Thanks a lot for all of you!
Well, I know that these two concepts are deeply discussed...but I still have questions for the following code:
#include <iostream>
using namespace std;
class A {
};
int N = 10;
void f(int p) {
int j = 1;
float k = 2.0;
A c;
A* d = new A();
static int l = 23;
static int m = 24;
cout << "&c: " << &c << endl;
cout << "&d: " << d << endl;
cout << "&j: " << &j << endl;
cout << "&k: " << &k << endl;
cout << "&l: " << &l << endl;
cout << "&m: " << &m << endl;
cout << "&p: " << &p << endl;
}
int main() {
int i = 0;
A* a;
A* b = new A();
cout << "&a: " << &a << endl;
cout << "&b: " << b << endl;
cout << "&i: " << &i << endl;
cout << "&N: " << &N << endl;
f(10);
return 0;
}
My result is:
&a: 0x28ff20
&b: 0x7c2990
&i: 0x28ff1c
&N: 0x443000
&c: 0x28fef3
&d: 0x7c0f00
&j: 0x28feec
&k: 0x28fee8
&l: 0x443004
&m: 0x443008
&p: 0x28ff00
This is pretty interesting, coz except the global variable N, and two static variables in function f, which are l and m, the addresses of all the other variables seem to be together. (Note: The code and the results have been modified and not corresponding to what is said here.)
I've searched a lot about stack and heap. The common sense is that, if an object is created by "new", then it is on the heap. And local variables (such as j and k in the above sample) are on stack. But it seems not to be the case in my example. Does it depend on different compilers, or my understanding is wrong?
Thanks a lot for all of you.
Your understanding is wrong. For example, b is a pointer - if you want the address of the object created by new, you need to print out b, not &b. b is a local variable, so it itself (found at &b) is on the stack.
For your example, N, l, and m are presumably somewhere in your executable's data section. As you can see, they have similar addresses. Every other variable you are printing out is on the stack - their addresses are likewise similar to one another. Some of them are pointers pointing to objects allocated from the heap, but none of your printouts would show that.
Your understanding is correct.
local variables are allocated on the stack.
dynamically allocated objects are allocated on the heap.
Though you are taking the address of the local variable consistently in your example.
Example: print out d not the address of d. As d is a local variable (so the address is similar to c) but it is a pointer variable that points at a dynamically allocated object (that is on the heap).
How the compiler implements the stack and heap though will vary.
In modern OS the stack and heap may even share the same area (ie you can implement the stack by allocating chunks in the heap).
If you want to print the address of whatever d points to (in this case it points to an object on the heap), do
cout << "d: " << d << endl;
That will print the value of the pointer, and the value of a pointer is the address of the object it points to.
Your code had
cout << "&d: " << &d << endl;
This prints the address of d , as you defined d inside main, it'll be on the stack, you're printing the address of your pointer. There's the pointer itself, and the object it points to, they're 2 seperate things, with seperate addresses.
The only ones that are not 'together' in your example are l, m and N. They are two statics and one global, therefore they are not allocated on the stack for sure. They aren't from a heap neither, most likely, they are from a .data segment of your module. The only one from a heap should be the address b points to, but you're printing the address of b itself, not what it points to.
The distinction between the two forms, from a pure C++ perspective, is only to do with how lifetime of objects are managed.
From here, good read
Static variables are in the data segment. Also you mix the address of a pointer and it value. For example a:
a is a local variable of type A* on the stack. &a also gives the address where a actaully resieds (on the stack). The value of a is an address of a heap object of type A;
You can't depend on various compilers doing things the same way. For almost every bit of code you will write the distinction between stack and heap are meaningless. Don't worry about it.
One may not safely assume anything about the relative addresses of things in the stack relative to those on the heap nor, for that matter, the relative addresses of any pointers that are not all derived from the same array or allocated (via malloc, calloc, etc.) block. I'm not even sure pointers are required to be rankable.