Accepting a pointer address? - c

This is the source code
#include<stdio.h>
void main()
{
int *p,a=5;
p=&a;
scanf("%d",p);
printf("%d\t",*p);
printf("%d",a);
}
How can we accept an address of a pointer?.Cuz it has the address of variable 'a' already.There are no errors shown by the compiler.
Also,i'm not able to understand the output.
output:(if my input is 45)
45 45

Your pointer is also a variable like a and has it's own address. You can access it by saying &p. But you say scanf("%d", p); so it is accessing pointer's pointing address.
EDIT: if you want to print pointer's address you can use printf("%p\n",(void *) &p);

You can access pointer itself by its address &p
int pa;
int *p;
scanf("%d", &pa);
p = (int*) pa;
printf("%p\t", p); // printing pointer stored address (got from input)
printf("%d\n", (void *) *p); // printing value stored in address stored in p, of course would be segfault in case of invalid address
Also use it with caution, its unportable and may resulting undefined behavior. it may work on 32bit machines because of int and int* have same length of bits but for other CPU's may not work.

Related

how to pass one pointer value to another pointer?like can I do int *a=*b;where b is defined already but the pointer a is not addressing to any integer

Actually I was reading about pointers and wanted to try something ,so I wrote a small code
int main(){
int x = 10;
int *ptr;
ptr = &x;
printf("%d is stored at address %d\n",x,ptr );
int *c=*ptr;
c=&ptr;
printf("location is %d\n",c);
printf("value of c= %d",*c);
}
the result I expected was value of c would be 10 but instead the value came as the location of x.
output: 10 is stored at address 997523644 location is 997523648 value of c= 997523644
does this problem arise because I didnt pass any location as first?or is it something else or my question is quite silly I know:D,Can anyone help me?
The first thing that is missing in the code that you have provided, is the declaration of ptr. You haven't declared the ptr variable yet, so first you need to do
int *ptr;
, which tells that you need a pointer variable to point to a int variable.
Since you declare another pointer int *c and ptr is already a pointer, you only need to assign int *c = ptr (or c=ptr in case you want to declare int *c seperately first), which will store the value of ptr (location of x) to c. So, doing int *c=*ptr is wrong. Now you can access the value of x by doing derefencing (*c or *ptr), which you already did.
Doing c=&ptr is also wrong, because c is of type int * and &ptr is of type int **. In case you are trying to store the address of ptr, you have to first declare a variable of type int **, for example int **d. Now d=&ptr is valid and d holds a value which is the address of ptr. Dereferencing d (*d) should give you the value that the address of ptr is holding, which is nothing but the address of x (same as the value of c). If you dereference d twice (**d), you should get the back the value of x (10).
int* c = ptr should be enough, you can read it as: c is pointer to integer, c = ptr since ptr is already a pointer this will make both c and ptr point to the same value.
What you are currently doing: c=&ptr; is making c point to the address of ptr, so if you want to access x value you will need to dereference twice, once to get the address of ptr, and once again to get the content of x.
Changed it to this:
#include <stdio.h>
int main(void) {
int x = 10;
int *ptr = &x;
printf("%d is stored at address %p\n",x,ptr );
int *c=ptr;
int d = &ptr;
printf("location is %p\n", c);
printf("value of c= %d", *c);
return 0;
}
As ptr is an address already, you can just do it:
int *c=ptr;
Output is:
10 is stored at address 0x7ffd6127dd54
location is 0x7ffd6127dd54
value of c= 10
To print variable address, you can check this answer:
Stackoverflow Answer
You just need to remove the line
c=&ptr;
The above line means that you're setting C as the location of ptr, which is some random value. So C points to the location of ptr, and ptr points to the location of x. C is a double-pointer
Alternatively, if you keep that line in there, you can make it work by instead printing
printf("value of c= %d",**c);
either solution would get the output you expect

difference between pointer and pointer location

This code prints different values for i and &i and both of them are not equal to 10. Please explain me what those two numbers indicate.
#include<stdio.h>
int main(){
int p=10;
int *i=&p;
printf("%d %d",i,&i);
}
This is what the output look like
i is an integer pointer that will be used to store address of a integer variable. In this case, i is stored in stack area of your main memory, when you print &i it means you print address of the place that storing i. When you print i it means you print value of i( value of i is address of p because you have assign &p to i by this line int *i=&p;). I hope it useful for you.
Here is a modified version of your code with comments in the printfs. Note that I added the third printf to reference your int that is in p
#include<stdio.h>
int main(){
int p=10;
int *i=&p;
printf("'i' = %p is the address of the int stored in variable p\n",(void *)i);
printf("'&i' = %p is the address of the pointer to an int called i\n",(void *)&i);
printf("'*i' = %d is the int that is stored at the location in i which points to p\n",*i);
}
'i' = 0x7ffee4e63abc is the address of the int stored in variable p
'&i' = 0x7ffee4e63ab0 is the address of the pointer to an int called i
'*i' = 10 is the int that is stored at the location in i which points to p

C: Why do pointer and &pointer have different values?

If I run the following on OS X:
int main (void)
{
int* n; // initialise(declare) pointer
*n = 20; // the value in address pointed to by n is 20
printf("n: %i, n&: %i\n", n, &n);
return 0;
}
I get:
n: 1592302512, n&: 1592302480
Why the differing values?
Why do pointer and &pointer have different values?
The expression &n yields the address of n itself, while n evaluates to the value of the pointer, i.e. the address of the thing it points to.
But note that you have undefined behaviour First of all, because you are de-referencing an uninitialized pointer. You need to make n point somewhere you can write to.
For example,
int* n;
int i = 42;
n = &i;
// now you can de-reference n
*n = 20;
Second, you have the wrong printf specifier for &n. You need %p:
printf("n: %i, &n: %p\n", n, &n);
int* n declares a variable called n which is a pointer to an integer.
&n returns the address of the variable n, which would be a pointer to a pointer-to-integer.
Let's say we have the following code:
int a = 20; // declare an integer a whose value 20
int* n = &a; // declare a pointer n whose value is the address of a
int** p = &n; // declare a pointer p whose value is the address of n
In this case we would have the following:
variable name | value | address in memory
a | 20 | 1592302512
n | 1592302512 | 1592302480
p | 1592302480 | who knows?
In your code
int* n; //initialization is not done
*n = 20;
invokes undefined behavior. You're trying to de-reference (write into) uninitialized memory. You have to allocate memory to n before de-referencing.
Apart form that part,
n is of type int *
&n will be of type int **
So, they are different and supposed to have different values.
That said, you should use %p format specifier with printf() to print the pointers.
Just as an alternative, let me spell this out a different way.
char *ptr;
char c='A';
ptr = &c;
In this code, here's what's happening and what values are found when we qualify ptr in different ways.
ptr itself contains the address in memory where the char c variable is located.
*ptr dereferences the pointer, returning the actual value of the variable c. In this case, a capital A.
&ptr will give you the address of the memory location that ptr represents. In other words, if you needed to know where the pointer itself was located rather than what the address is of the thing that it points to, this is how you get it.

If p is a pointer to int where would one use &p

In the following code p is pointer to an int. It is quite clear that p points to the address of i. Through my research i know &p points to the address of pointer p. But i don't get why would you need separate address for that. And also when would you use &p.
int main() {
int i = 3, *p = &i;
printf("%p",&p);
printf("%p",p);
return 0;
}
If p is pointer to int then
int **q = &p;
When you want to use pointer to pointer, then use the address of a single pointer to assign it to pointer to pointer.
Just to make a point that pointer is also a data-type and it stored in the memory location and it holds a valid memory location as its value. The address in which this valid memory location is stored is given by &p
Your printf() also needs to be fixed. %p expects void *
printf("%p",(void *)p);
But i don't get why would you need separate address for that
You don't, but there exists the address of operator so you can take the address of a pointer, which is what
printf("%p\n", &p);
is printing.
And also when would you use &p
There are cases where this might be useful, consider for example that you need to pass a pointer to a function which could be reassigned into the function, you can do something like this
int allocateIntegerArray(int **pointerToPointer, size_t someSize)
{
if (pointerToPointer == NULL)
return 0;
*pointerToPointer = malloc(someSize * sizeof(int));
return (*pointerToPointer != NULL);
}
then you could use this funciton the following way
int *pointer;
if (allocateIntergerArray(&pointer, 10) == 0)
{
fprintf(stderr, "Error, cannot allocate integer array\n");
/* do some extra cleanup or recover from this error, or exit() */
exit(0);
}
The pointers themselves are also variables and as such they need to be sotred somewhere, so the address of a pointer tells you where is the pointer stored, it's value tells you where it is pointing to.
By knowing where it is stored you can do things like the one explained above.
A trivial example:
int nochange(int *c, int *val)
{
c = val; // Changes local pointer c to point to val
// Note that C passes copies of the arguments, not actual references.
}
int do_change(int **c, int *val)
{
*c = val; // Accesses the real pointer c at its real location and makes
// that one point to val
// Even though c is a pointer-to-pointer copy, its value is
// copied too, and the value is the address of the real c
}
int main()
{
int a = 1;
int b = 2;
int *c = &a; // A pointer is also a datatype that resides in memory
printf("%d\n", *c); // Will print 1
nochange(c, &b);
printf("%d\n", *c); // Will print 1
do_change(&c, &b);
printf("%d\n", *c); // Will print 2 because c now points to b
}
I have a similar answer with a bit more detail here about pointer vs pointer-to-pointer: pointer of a pointer in linked list append

c struct question

#include <stdio.h>
struct audiocd {
char title[256];
int trackNo;
char type;
char publisher[256];
};
int main() {
struct audiocd* cdptr;
struct audiocd cdarray[4];
cdptr = cdarray;
printf("%d\n", &(cdarray[2]));
printf("%d\n", cdptr);
}
What is cdarray[2] & cdptr?
EDIT: Thanks, but if printf("%d\n", &cdarray) is 4291520 , is it possible to trace printf("%d\n", &(cdarray[2])) & printf("%d\n", cdptr)?
The overall effect of the program is simply undefined behavior. It's passing addresses to printf, but using the %d conversion, which expects an int. The mismatch causes undefined behavior.
In a typical case that int and a pointer happen to be the same size, it'll print out the address in cdptr and the address of cdarray[2].
If you want to print out those addresses, the obvious way is something like:
printf("%p", (void *)&cdarray[2]); // (void *)cdarray+2
printf("%p", (void *)cdptr);
As for what those expressions "are", they're addresses -- the addresses of the beginning of the array and the third element of the array, respectively.
thanks, but if printf("%d\n",
&cdarray) is 4291520 , is it possible
to trace printf("%d\n", &(cdarray[2]))
& printf("%d\n", cdptr).
If I got your question correctly, I think you want to infer the values of &(cdarray[2]) and &(cdptr) from value of cdarray.
As you assigned cdarray to cdptr, cdptr will store the starting address of the array. Now &(cdarray[2]) is just
cdarray + 2*sizeof(struct audiocd)
Also, as discussed above, %p should be used to print memory addresses instead of %d.

Resources