Pointers when reassigned still points to old value - c++

Here, two variables a=1,b=2 and three pointer variables *p2a = &a , *q2p = p2a , *r2b = &b .
When I change *p2a to point to *r2b, then pointer *q2p which is pointing to *p2a should also change right? . But *q2p still points to old value pointed by *p2q and not the new value of newly pointed *p2q which is the value of b pointed by *r2b.
#include <iostream>
using namespace std;
int main() {
int a = 1;
int b = 2;
int* p2a = &a;
int* q2p = p2a;
int* r2b = &b;
p2a = r2b;
cout << *q2p;
return 0;
}
Output:
1
My understanding of pointers is not that good. So If my question is really dumb I'm sry for it.
If you feel hard to get the problem description, then simply my question is, Why *q2p value is not changed when *p2q is changed to point to *r2b, but still *q2p pointing to old value of *p2q.

No, q2p is not a an int** (pointing at the pointer p2a), so
int* p2a = &a;
int* q2p = p2a; // q2p is pointing at "a"
// ...
int* r2b = &b;
p2a = r2b; // q2p is still pointing at "a"

Related

What happens to values on the stack that get placed in array on the Heap

I want to know if I create an array on the Heap in C++ and I assign data from the stack to the Array, what exactly happens? Is the data copied onto the heap?
code fragment:
int a = 1;
int b = 2;
int *c = new int(3);
int *arr = new int[3];
arr[0] = a;
arr[1] = b;
arr[2] = *c;
int a = 3;
a has the value 3.
the memory address of a is 0x345A or something like it.
a is on the stack.
int *p = &a;
pointer p is assigned the address of a. The memory address of p is 0x123B or something like it. That memory address holds the value 0x345A pointing to the location where the value 3 is stored. Pointer p is on the stack.
You'd get 3 if you print a and *p since they are getting their value from the same memory location.
You'd get 0x345A if you print &a and p since a's address is the value p holds.
You'd get 0x123B if you print &p since that is the memory location for pointer p.
Assuming *c points to an integer on the heap, you could store the value of c (which is the memory address of the integer on heap) in an array.
int *arr = new int[3];
...
arr[2] = c;
What you do NOT want to do is:
int foo = 10;
arr[2] = &foo;
Now, your array is pointing to a memory location that that is on the stack. Will work OK as long as you are in that function, but will be pointing at garbage once you exit the function and stack is reclaimed.

Pointers with runtime allocation

I don't get that why reassigning a value to *p shows error. We've deleted it's resources, created at run time.
int a = 7, b = 8;
int *p = new int;
*p = a;
cout<<*p<<" "<<p<<endl;
delete p;
cout<<*p<<" "<<p;
*p = &b; // error
cout<<"\n"<<*p<<" "<<p;
The behaviour on dereferencing p after you've called delete p; is undefined. Don't do that. That's the easy bit. Now for the harder bit: the behaviour on reading the value of p (let alone dereferencing it) following a call to delete is undefined too! So don't do that either. (Informally you put the pointer back to an uninitialised state.)
*p = &b; is a typo. You need p = &b; to assign the pointer p to the address of b. If you fix that typo, you are free to read the value of p and dereference it once again.
The problem besides deleting the pointer and not giving it a new address is currently you are trying to assign the value of the p pointer to a memory address of an int.

Not able to understand the notations : * and ** with pointers

I have a problem with the pointers. I know what this does:
*name
I understand that this is a pointer.
I've been searching but I do neither understand what this one does nor I've found helpful information
**name
The context is int **name, not multiplication
Could someone help me?
NOTE: Without the proper context, the usage of *name and **name is ambiguous. it may portrait (a). dereference operator (b) multiplication operator
Considering you're talking about a scenario like
char * name;
char **name;
in the code,
*name
name is a pointer to a char.
**name
name is a pointer, to the pointer to a char.
Please don't get confused with "double-pointer", which is sometimes used to denote pointer to a pointer but actually supposed to mean a pointer to a double data type variable.
A visual below
As above, we can say
char value = `c`;
char *p2 = &value; // &value is 8000, so p2 == 8000, &p2 == 5000
char **p1 = &p2; // &p2 == 5000, p1 == 5000
So, p1 here, is a pointer-to-pointer. Hope this make things clear now.
It's actually very simple, consider this:
int a; // a is an int
int* b; // b is a pointer to an int
int** c; // c is a pointer to a pointer to an int
If you see every level as just another variable type (so, see *int as a type), it's easier to understand.
Another example:
typedef int* IntPointer;
IntPointer a; // a is an IntPointer
IntPointer* b; // b is a pointer to an IntPointer!
Hope that helps!
pointer stores address of variable, pointer to pointer stores address of another pointer.
int var
int *ptr;
int **ptr2;
ptr = &var;
ptr2 = &ptr;
cout << "var : " << var;
cout << "*ptr : " << *ptr;
cout << "**ptr2 : " << **ptr2;
You can look here
int a = 5;// a is int, a = 5.
int *p1 = &a; // p1 is pointer, p1 point to physical address of a;
int **p2 = &p1; // p2 is pointer of pointer, p2 point to physical adress of p1;
cout<< "a = "<<a << " *p1 = "<<*p1<<" *(*p2) = " << *(*p2)<<endl;
**name in this case. Would be a pointer to a pointer.

Can a Pointer variable holds the address of another Pointer Variable?

Is it possible to make a pointer variable hold the address of another pointer variable? eg:int a;
int *ptr,*ptr1;
ptr=&a;
ptr1=&ptr;
Sure, a pointer to a pointer.
int i;
int *pi = &i;
int **ppi = π
There is nothing particularly unusual about a pointer to a pointer. It's a variable like any other, and it contains the address of a variable like any other. It's just a matter of setting the correct type so that the compiler knows what to do with them.
Yes, but it needs to have the right type. In your example int *ptr,*ptr1; both ptr and ptr1 have type "pointer to int", which can only point to an int, not a pointer. If you declare int *ptr, **ptr1;, then ptr1 has type "pointer to int *" and thus can point to ptr.
Here's a sample showing what happens
int a = 13;
int *ptr,
int **ptr1; // ** means pointer to pointer
ptr = &a;
ptr1 = &ptr;
cout << a; //value of a
cout << *ptr; //ptr points to a, *ptr is value of a
cout << **ptr1; //same as above
cout << &ptr; //prints out the address of ptr
cout << *ptr1; //same as above
It works the same for int ***ptr, int ****ptr.
Pointer to pointer is possible (and very common), but int* may not be large enough to contain the address of another int*. use int**. (or void*, for generally pointer)
There's two answers here and they're both yes.
Two pointers can point to the same location
int b, *p1=&b, *p2=&b;
*p1 = 123;
*p2; // equals 123
You can also have a pointer to a pointer:
int x=2, y=3, *p=&x, **q=&p;
Note the extra asterisk.
**q; // equals 2
*q = &y;
**q; // equals 3
**q = 4;
y; // equals 4
Yes,
Pls see the following code. I hope it will serve your purpose
int a = 4;
int *ptr = &a;
int *ptr1 = (int*)&ptr;
cout << **(int**)ptr1;
Here ptr1 is single pointer but behaves as double pointer

Pointers problem

I have a question.
I created a correctly initialized integer pointer
int * p
and a correctly initialized integer array
int * array1 = new int[]
Which of the following is legal code?
p = array1;
array1 = p;
Or are both correct?
is this possible as well
p[0] since, to my pointer arithmetic knowledge, it doesn't add anything.
All in c++
If the question is trying to get at pointers versus arrays, they are not always compatible. This is hidden in the presented code because the array is immediately converted to a pointer.
int* array1 = new int[5]; // Legal, initialising pointer with heap allocated array
int array2[5] = {0}; // Declaring array directly on the stack and initalising with zeros
int *p = 0; // Declaring pointer and initialising to numm
p = array2; // Legal, assigning array to pointer
p = array1; // Legal, assigning pointer to pointer
array1 = p; // Legal, assigning pointer to pointer
array2 = p; // ILLEGAL, assigning pointer to array
Here array2 has an array type and cannot be used to store a pointer. Actually, the array cannot be reassigned at all, as it is not an l-value.
int array3[5] = {0}; // Declaring array directly on the stack and initalising with zeroes
array3 = array2; // ILLEGAL, array not an l-value
The array has a fixed address and reassiging it would be similar to trying to write:
int i = 0;
&i = p;
[Hopefully, trying to reassign the location of a variable is obvious nonsense.]
Both are legal.
The first, "p = array1", will cause your correctly initialized integer pointer to be leaked and to point p to the first occurrence of the array that array1 points to.
The second, "array1 = p", will cause the correctly initialized integer array to to be leaked and to point array1 to the single int that p points to.
So I suspect I'm missing something. Could you perhaps post complete code?
If both p and array1 are declared as "int *", as you imply here, then either assignment is legal, by definition.
both are leagal.
passing adresses to eachother. dont knw what u want to do
According to the explanation provided in this site. The first assigned in is correct but the second assignment cannot be considered valid. Please look under the title 'Pointers and arrays'.
You can assign your array variable to pointer variable. So p = array1 is correct.
You can refer this code.
#include <iostream>
using namespace std;
int main ()
{
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
for (int n=0; n<5; n++)
cout << p[n] << ", ";
return 0;
}
If both are pointers then no need to declare pointer as array like int *array1 = new int[].
Both variables are of type pointer to int. So both assignments are legal. The fact that one of the variables is an array doesn't matter in C. Arrays and pointers are the same after initialization.
"I created a correctly initialized integer pointer int * p and a correctly initialized integer array int * array1 = new int[]"
First of all, keeping the syntactical mistakes aside, the terminology is wrong.
int *p; - Here you are just declaring a pointer to hold an integer variable's address. You are not initializing it. Declaration is different from initialization and initialization is different from assignment.
int *array1 = new int[]; - Keeping the error aside, this is not an initialized integer array. array1 is a pointer pointing to an array of integers.
And passing nothing to [] is incorrect. A value needs to be passed that decides number of memory locations to be allocated for holding integer values.
Answering the questions.
Which of the following is legal code?
p = array1;
If, array1 is properly initialized it's correct. p points to the first integer in the array1. Even if it is not properly initialized also, it is correct. In this case, both array and p points to garbage values.
int* array1 = new int[5]; // Notice **5** being passed.
array1 = p;
Infact this operation is useless. Both p and array1 were both pointing to the same location earlier. But this is legally correct.
is this possible as well p[0] ?
Yes, it's correct. p can dereference to 0 to 4 as it's index values. If you just want to p[0], in that case -
int* array1 = new int ; // Notice nothing being passed.