Pointers and addresses in C++ - c++

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!

Related

Two pointers to the same location?

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.

Dereference a structure to get value of first member

I found out that address of first element of structure is same as the address of structure. But dereferencing address of structure doesn't return me value of first data member. However dereferencing address of first data member does return it's value. eg. Address of structure=100, address of first element of structure is also 100. Now dereferencing should work in the same way on both.
Code:
#include <iostream>
#include <cstring>
struct things{
int good;
int bad;
};
int main()
{
things *ptr = new things;
ptr->bad = 3;
ptr->good = 7;
std::cout << *(&(ptr->good)) <<" " << &(ptr->good) << std::endl;
std::cout << "ptr also print same address = " << ptr << std::endl;
std::cout << "But *ptr does not print 7 and gives compile time error. Why ?" << *ptr << std::endl;
return 0;
}
*ptr returns to you an instance of type of things, for which there is no operator << defined, hence the compile-time error.
A struct is not the same as an array†. That is, it doesn't necessarily decay to a pointer to its first element. The compiler, in fact, is free to (and often does) insert padding in a struct so that it aligns to certain byte boundaries‡. So even if a struct could decay in the same way as an array (bad idea), simply printing it would not guarantee printing of the first element!
† I mean a C-Style array like int[]
‡ These boundaries are implementation-dependent and can often be controlled in some manner via preprocessor statements like pragma pack
Try any of these:
#include <iostream>
#include <cstring>
struct things{
int good;
int bad;
};
int main()
{
things *ptr = new things;
ptr->bad = 3;
ptr->good = 7;
std::cout << *(int*)ptr << std::endl;
std::cout << *reinterpret_cast<int*>(ptr) << std::endl;
int* p = reinterpret_cast<int*>(ptr);
std::cout << *p << std::endl;
return 0;
}
You can do a cast of the pointer to Struct, to a pointer to the first element of the struct so the compiler knows what size and alignment to use to collect the value from memory.
If you want a "clean" cast, you can consider converting it to "VOID pointer" first.
_ (Struct*) to (VOID*) to (FirstElem*) _
Also see:
Pointers in Stackoverflow
Hope it helps!!
I found out that address of first element of structure is same as the address of structure.
Wherever you found this out, it wasn't the c++ standard. It's an incorrect assumption in the general case.
There is nothing but misery and pain for you if you continue down this path.

Variable given same address as the pointer that is pointing to it

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.

Memory address in dynamic allocation

#include <iostream>
int main()
{
int anything[] = {5};
int *something = new int;
*something = 5;
std::cout << &anything << "==" << &anything[0] << "==" << anything << std::endl;
std::cout << &something << "!=" << &something[0] << "==" << something << std::endl;
}
Why is the memory address in &something different from &something[0] and something? Although it is a dynamic allocation, I don't understand why the memory address is different. I tried it with more than one value; it's the same thing. Here I used one value for both for simplicity.
&something is the memory address of the pointer itself (hey, it needs to store that value somewhere!), while &something[0] is the address of the actual memory that is storing your stuff.
something is a pointer. &something is the address of that pointer. &something[0] is the address of the first element pointed to by the pointer, which is completely different from the address of the pointer. something is the value of the pointer, which is also the address of the element that is pointed to.
I'm sure this topic has been covered many times before, I hope I did it justice.

Address of Stack and Heap in C++

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.