Why is it pointing to the same address? - c

#include<stdio.h>
int main() {
int x = 5;
int* p = &x;
*p = 6;
int** q = &p;
int *** r= &q;
printf("%d\n",*p); //dereferencing p
printf("%d\n",*q); //getting address of q
printf("%d\n",**q); //dereferencing q
printf("%d\n",**r); //getting address of r
printf("%d\n",***r); //dereferencing r
}
Variable q has the memory address of p while variable r has the memory address of q, then why does when trying to print the memory address of q and r same results are getting produced?

Your comments show that you have misunderstood a few things here.
printf("%d\n",*q); //getting address of q
You're NOT getting the address of q. You're dereferencing q, which happens to be the address of p. The * IS the dereferencing operator. If you want to print the address of q, then do this:
printf("%p\n", (void*)&q); // No asterisk and you should use the %p specifier for printing pointers.
So, because you have made the assignment p=&x; q=&p; then
**q is the same as x or *p
*q is the same as p
q is the the same as &p
&q is the address of q

Related

"lvalue required as left operand of assignment" when using pointers in C

I want to practice with pointers in C. I got an error showing "lvalue required as left operand of assignment". The error shows at &y=&x. So how could I over wright the address of x to y?
int main()
{
int x=3;
int y=4;
&y=&x;
printf("x=%p,y=%p",&x,&y);
return 0;
}
y is a variable, &y is not so can't be changed. &y is just a way to get the address of that variable.
The address of a variable is immutable. They are not allowed to be changed.
What you can do is store that address in a pointer variable, and later change that pointer to point to something else:
int x=3, y=4;
int *p;
p = &x;
*p = 2;
printf("p=%p, &x=%p\n", (void *)p, (void *)&x); // prints same value both times
printf("x=%d\n", x); // prints 2
p = &y;
*p = 7;
printf("p=%p, &y=%p\n", (void *)p, (void *)&y); // prints same value both times
printf("y=%d\n", y); // prints 7

Pointer to pointer as argument in a function

I have the following code:
void change_adrs(int **q)
{
int * otheraddess;
*q = otheraddress;
}
I can't understand this assignment: *q = otheraddress;
Could anybody help me to explain this. Why can't we use another assignment, such as:
**q = otheraddress;
*q = *otheraddress;
q = &otheraddress;
void change_ptr(int **q)
{
*q = malloc(somemem);
}
void foo()
{
int *ptr;
change_ptr(&ptr);
}
in this example it will change the value of the ptr itself. When you pass a single star pointer you can only change the referenced object.
Look at the assignment of *q = otheraddress; the same as you look at the following:
int x = 4;
int y = x;
you take 2 vairables of the same type and make an assignment between both of them.
In your case, you use the address of int vairables.
int *otheraddress; is a vairable who can get an address (& operator) to int vairable such as:
int x = 4;
int *p = &x; //p<=the address of x
and int **q; can get an address of a vairable which can get int address. such as you 3rd assignment (which should work fine):
int x = 4;
int *p = &x;//p<=the address of x
int **q = &p;//q<=the address of p
for the other assignmets:
**q = otheraddress; you try to assign int* into int**
*q = *otheraddress; you try to assign int into int *
After declaring the variables, * dereferences them.
For example after declaring something like int **a;, when using it we have:
**a value in value in location stored in a(which is ultimately an int)
*a value in location stored in a (which is another location)
a location stored in a
&a location of a itself
Lets take a look and see why each of your examples don't work:
**q = otheraddress; assigning a location to an int ×
*q = *otheraddress; assigning an int to a location ×
Edit: Lets take a look at these two examples:
q = &otheraddress; assigning a location to a location ✓
*q = otheraddress; assigning a location to a location ✓
Lets look at it this way:
Suppose we have:
int *a;
int **q;
in order to prevent segmentation faults in the future, lets first assign some address to a:
int t = 5
a = &t;
Lets look at the addresses afterq = &a:
//first snippet
0x7fffc3a2b338 // &a
0x5596853c98c0 // a
5 // *a
0x7fffc3a2b340 // &q
0x7fffc3a2b338 // q
0x5596853c98c0 // *q
5 // **q
As expected, &a is put into q, and a holds &t, so **(&a) and **(q) will both hold a value of 5.
Now lets look at the addresses after*q = a:
//second snippet
0x7fffc3a2b338 // &a
0x5596853c98c0 // a
5 // *a
0x7fffc3a2b340 // &q
0x7fffc3a2b345 // q
0x5596853c98c0 // *q
5 // **q
Here, a is put into *q, and a itself is &t, so *(a) and *(*q) with both hold a value of 5.
To understand the difference, we look at an example:
int b = 3;
a = &b;
Using this after the first snippet, a is given another address, and q was declared &a(which hasn't changed), therefore **(q) has the same value as **(&a), which is now 3.
This is just like saying:
int a = 3;
int *b = &a;
a = 5; //even though a has changed, b retains its old value of &a, thus *(b) == *(&a) == 5
However on the second snippet, *q was already declared as a before it had changed, so even though a now has a new address, the address inside *q still hasn't changed. Thus trying to access *(*q) will use the old address and give us 5 again.
This is just like saying:
int a = 3;
int b = a;
a = 5; //even though a has changed, b still retains it's old value of 3

segmentation fault in this pointers program in C

I keep getting a segmentation fault (core dumped) message whenever I try to run this C program.
#include <stdio.h>
int main()
{
int i = 200, *p, *q, *r;
p,r = &i;
q = p;
*q = *p + 1;
printf("*p = %d\n", *p);
printf("*r = %d\n", *r);
return 0;
}
It didn't have any rs at first but I had to add rs as an alias to i and then Add print statements to output the dereferenced values of q and r.
In your code
p,r = &i;
does not assign p, it leaves p uninitialized. Next, the very moment you dereference p (and q also, as it was assigned with the value of p) you hit
undefined behavior, as you're dereferencing invalid memory.
You need to use
p = r = &i;
Compile your code with proper warnings enabled and, with your code, you should see something similar to
warning: left-hand operand of comma expression has no effect [-Wunused-value]
p,r = &i;
^
Use this:
p = &i;
r = &i;
instead of
p,r = &i;
Uninitialized pointer is bad.
//I write that as an answer because i still don't have 50 reputation
1: I didn't understand what do you want that the program will do. the use of q and r is useless.
2: p,r=&i; is not a good command. use p=r=&i or p=&i; r=&i; or
p=&i; r=p;
i have made the correction in your code and it is working fine please have look into it.
`#include <stdio.h>
int main()
{
int i = 200, *p, *q, *r;
p = &i;
r = &i;
q = p;
*q = *p + 1;
printf("*p = %d\n", *p);
printf("*r = %d\n", *r);
return 0;
}`

Printing a variable in C that was not assigned a value

I put this code into eclipse and run it
main()
{
int *p, *q, *r;
int a = 10, b = 25;
int c[4] = {6,12,18,24};
p = c;
printf("p = %d\n" ,p);
}
the output I get is
p = 2358752
what is this number supposed to represent? Is it the address of the variable?
If what i'm saying above is true would my answer to the following question be correct?
so lets say the following are stored at the following locations
address variables
5000 p
5004 q
5008 r
500C a
5010 b
5014 c[0]
5018 c[1]
501C c[2]
5020 c[3]
so would would the line
p = c;
be 5014?
int *p,
The above statement defines p to be a pointer to an integer.
In the below statement, c is implicitly converted to a pointer to the first element of the array a.
p = c;
// equivalent to
p = &c[0];
Therefore, p contains the address of the first element of the array. Also, the conversion specifier to print an address is %p.
printf("p = %p\n", (void *)p);
// prints the same address
printf("c = %p\n", (void *)c);
Yes, p is the address of c, which is the same as the address of c[0]. And yes, in your second example, p would be equal to 5014.

Casting pointer & its address to integer pointer

What is the difference between the following two assignments?
int main()
{
int a=10;
int* p= &a;
int* q = (int*)p; <-------------------------
int* r = (int*)&p; <-------------------------
}
I am very much confused about the behavior of the two declarations.
When should i use one over the other?
int* q = (int*)p;
Is correct, albeit too verbose. int* q = p is sufficient. Both q and p are int pointers.
int* r = (int*)&p;
Is incorrect (logically, although it might compile), since &p is an int** but r is a int*. I can't think of a situation where you'd want this.
#include <stdio.h>
int main()
{
int a = 10; /* a has been initialized with value 10*/
int * p = &a; /* a address has been given to variable p which is a integer type pointer
* which means, p will be pointing to the value on address of a*/
int * q = p ; /*q is a pointer to an integer, q which is having the value contained by p, * q--> p --> &a; these will be *(pointer) to value of a which is 10;
int * r = (int*) &p;/* this is correct because r keeping address of p,
* which means p value will be pointer by r but if u want
* to reference a, its not so correct.
* int ** r = &p;
* r-->(&p)--->*(&p)-->**(&p)
*/
return 0;
}
int main()
{
int a=10;
int* p= &a;
int* q = p; /* q and p both point to a */
int* r = (int*)&p; /* this is not correct: */
int **r = &p; /* this is correct, r points to p, p points to a */
*r = 0; /* now r still points to p, but p points to NULL, a is still 10 */
}
Types matter.
The expression p has type int * (pointer to int), so the expression &p has type int ** (pointer to pointer to int). These are different, incompatible types; you cannot assign a value of type int ** to a variable of type int * without an explicit cast.
The proper thing to do would be to write
int *q = p;
int **r = &p;
You should never use an explicit cast in an assignment unless you know why you need to convert the value to a different type.

Resources