Why in this code the pointer shifts to another location:
#include <stdio.h>
void f(int *p)
{
int j=2;
p=&j;
printf("%d\n%p\n%d\n",*p,&j,p);
}
int main(void)
{
int *q;
int m=98;
q=&m;
f(q);
printf("%p ",q);
return 0;
}
Output:
2
0x7ffff5bf1bcc
0x7ffff5bf1bcc
0x7ffff5bf1bc8
I understand that when the function f() is done with printing value of j and address of j the memory occupied by j goes back to the stack but IMO p should continue pointing that location even after the function is over & it should be printing the same address in main as well. What is wrong with this?
Considering you meant printf("%p ", (void *)q); in the actual code,
No, function argument(s) in C is (are) passed by value. It won't reflect the changes made to the parameter into the actual arguments used (in function call) themselves.
To put it into other words, the function parameters are local to the function (call) scope, any changes made to them won't be reflected to the actual arguments.
So, if you need to change a pointer, you need to pass a pointer to the pointer which needs to be changed.
Consider a rather light-hearted but realistic scenario.
void f (int x) { x = 10; }
int main(void) { f(5); printf ("%d", 5); return 0;}
Now, do you expect it to print 10?
That said, an advice. Always cast the argument to %p conversion specifier to (void *) (if it is not already). printf() is a variadic function and for pointers, no default argument promotion happens, so the supplied argument type needs to match the expected type, explicitly. Otherwise, technically it is undefined behavior.
Learn the difference between Pointers and Pointers to pointers - the pointer passed p is no doubt good to change the value of the variable it is pointing to (m), but to change the memory location it is pointing to - you need a pointer to pointer.
Expanding on top of what #SouravGhosh said, when you pass in a pointer to an int you are making a copy of the pointer. If you wanted to change the pointer you need to be doubly indirect and pass in a pointer to a pointer to an int. The first pointer is copied and you can directly affect the second pointer.
void f(int ** p)
{
int j = 2;
*p = &j;
printf("%d\n%p\n%p\n",*p,&j,p);
}
int main(void)
{
int ** q = (int **)malloc( izeof(int *));
int m = 98;
*q = &m;
f(q);
printf("%p ",q);
free(q);
return 0;
}
And the output is
2
0xffffcbcc
0xffffcbcc
0xffffcbcc
If you do this you'll see that it never changes:
#include <iostream>
#include "Header2.h"
#include "header1.h"
#include <stdio.h>
void f(int *p)
{
int j = 2;
p = &j;
printf("%d\n%p\n%p\n", *p, &j, p);
}
int main(void)
{
int *q;
int m = 98;
q = &m;
printf("Value of pointer q before calling f() =%p ", q);
f(q);
printf("Value of pointer q after calling f() =%p ", q);
return 0;
}
Related
The value in the printf hasn't changed after applying the void function f, which is confusing me. It's basic stuff revolving pointers. The exact question is: Why isn't the end value 2 instead of 1?
int a=1, b=2;
void f(int* p) {
p=&b;
}
int main() {
int *p=&a;
f(p);
printf("%d\n", *p);
}
The *p value in main remains 1, and that's what's confusing me.
You need to dereference p and remove the & address operator from b
This assigns the value of b to the address where p points to:
void f(int* p)
{
*p = b;
}
The reson why it printed 1 and not e.g. the address of b is that you assigned: p = &b which just assigns the address of b to the local pointer variable p. This means it does not point to a anymore here. But since this was just a local copy it didn't change the value of the p you passed in main().
This makes it a little more obvious:
void f(int* ptr)
{
// assign a value
*ptr = 1337;
}
int main()
{
int local_integer = 666;
// prints "666"
printf("%d\n", local_integer);
f(&local_integer);
// prints "1337"
printf("%d\n", local_integer);
}
In your code you define a pointer to int on the stack. Its value is the same as the pointer in the main() function which happens to point to the ąddress of the variable a. Then you change its value (so the pointer on the stack now points to b) then you just drop that pointer.
void f(int* p) {
p=&b;
}
That is why if you dereference the pointer in main it still points to the address of the int variable a.
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
I have been using java for long time but for some reason I need to use C (ANSI C not C++) to write a simple code. I need to pass the pointer from outside to a function, allocate some memory to the pointer and assign some values also before the function return. I have my code like
#include <stdio.h>
#include <stdlib.h>
void test(int *a)
{
int n=3;
// I have to call another function t determine the size of the array
n = estimatesize(); // n >=3
// I tried fix size n=10 also
a = (int*)malloc(n*sizeof(int));
a[0] = 1;
a[1] = 2;
a[2] = 3;
}
void main(void)
{
int *s=NULL;
test(s);
printf("%d %d %d", s[0], s[1], s[2]);
}
I don't know why the code crashes. I thought at the beginning it is estimatesize() return wrong number but even I fix n to 10, the error still there. So I cannot pass a pointer to a function for memory allocation? If so, how can I dynamically create memory inside a function and pass it out? I know it may be a safe problem in this way but I just want to know if it is possible and how to do that. Thanks.
There are two solutions to this: Either return the pointer from the function, or pass the argument by reference.
For the first one, you simply don't take any arguments, instead you return the pointer:
int *test(void)
{
int *a = malloc(...);
...
return a;
}
int main(void)
{
int *s = test();
...
}
For the second one, you need to pass the address of the pointer, in other words a pointer to the pointer, using the address-of operator &:
void test(int **a)
{
*a = malloc(sizeof(int) * 3);
for (int i = 0; i < 3; ++i)
(*a)[i] = i;
}
int main(void)
{
int *s;
test(&s);
...
}
The reason it doesn't work now, is because the pointer (s in main) is passed by copying it. So the function test have a local copy, whose scope is only in the test function. Any changes to a in the test function will be lost once the function returns. And as s is copied for the argument, that means that s in main never actually changes value, it's still NULL after the function call.
Please find the code snippet as shown below:
#include <stdio.h>
int My_func(int **);
int main()
{
int a =5;
int *p = &a;
My_Func(&p);
printf("The val of *p is %d\n,*p);
}
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
*p = Ptr;
}
How does by using a double pointer as a argument in my_Func function and making change of value reflects the same in the main function but if we use a single pointer in My_Func does not change the value in main?Please do explain me with examples if possible
Advanced thanks
Maddy
int **p is a pointer to a pointer-to-int. My_Func(int **p) works by changing the value of integer that the pointer-to-int points to i.e. int a.
Without changing the implementation, the function will not work with a pointer-to-int parameter int *p as there is a second level of indirection. In addition, you're setting the value to a local variable that is created on the stack. When the function is completed the memory used for the variable will be reclaimed, therefore making the value of a invalid.
void My_Func(int **p)
{
int val = 100; // Local variable.
int *Ptr = &val; // This isn't needed.
*p = Ptr;
} // val dissapears.
Remove the second level of indirection and copy val by value instead of pointing to it:
#include <stdio.h>
void My_Func(int *p)
{
int val = 100;
*p = val;
}
int main(void)
{
int a = 5;
My_Func(&a);
printf("The val of a is %d\n", a);
return 0;
}
In short, in C when you pass something as a parameter, a copy will be passed to the function. Changing the copy doesn't affect the original value.
However, if the value is a pointer, what it points to can be changed. In this case, if you want to affect the pointer, you need to pass a pointer to it down to the function.
Use it in the function declaration:
void func(int *p)
{
int val =100;
int *temp=&val;
p=temp;
}
p starts pointing to another address i.e. address of val. So it will print the value 100.
Important note: Try it in your downloaded compiler (always in case of pointers) not in the online compiler. The online compiler doesn´t keep track of lost addresses in stack.
You are assigning the address of local variable, which will soon disappear when My_Func returns. You can use following in your code. However you can do the same thing just by using single pointer, double pointer is not required in this example.
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
**p = *Ptr;
}
I have been trying to create a pointer variable in the called function and somehow pass the value pointed by it to the main function. I wrote a few sample programs but it i still seem to be missing something out. and the challenge was to achieve this using pointers to pointers to pointers. Here is the code that I wrote and tested. I think am missing something obvious, can you guys point it. Thanks.
int one(int ***ptr)
{
static int *p,**pp,b=10;
p=&b;
pp=&p;
ptr=&pp;
printf("b:%d\tp:%d\tpp:%d\n",b,*p,**pp);
printf("Sub Ptr:%d\n",***ptr);
printf("Address of ***ptr:%d\n",&ptr);
return 32;
}
int main(int argc, char *argv[])
{
static int ***ptr;
int a=200,*b,**c;
b=&a;
c=&b;
ptr=&c;
printf("Main Ptr:%d\n",&ptr);
a=one(ptr);
printf("Main Ptr:%d\n",&ptr);
printf("Main Ptr:%d\n",***ptr);
system("PAUSE");
return 0;
}
I get an output of 32 which is the return value of the function. Is it possible to get the value of 10 which is pointed in the called function.
I also tried global declaration but din work either. I would like to maintain the local declaration and see if its possible...
I think you misunderstood about pointers. The problem of your code is that you didn't realize that pointer is also "pass by value", the pointer in the function is another variable on the stack, instead of the one you declare in the main function.
I would use a more simple example, but the idea is the same.
void changePointerValue (int * ptr)
{
int newValue = 10;
ptr = &newValue;
}
int main ()
{
int x = 20;
int * ptr = &x;
changePointerValue (ptr);
printf ("After Change: %d\n", *ptr);
}
What value do you think it will output in main function? Is that be 10?
But no, in fact, it will output 20.
Why? Let's look what our code does. In the line of chagePointerValue(ptr), the computer copy the value of ptr in the main function to a new varaible on stack, let's call it ptr' and pass it to the changePointerValue function.
So in fact the ptr in the changePointerValue function is ptr', not the one you declare in the main function. The second line of changePointerValue, you assigned a new memory address to ptr', and after that, ptr' is discarded because the function is returned. The ptr in the main function remains the same value, which is the memory address pointed to x.
If you want the output to be 10, you need deference ptr in the changePointerValue, and the assignement will means 'Change the value where the ptr is pointed at'.
void changePointerValue (int * ptr)
{
int newValue = 10;
*ptr = newValue; // Now you are change the content of the memroy cell where ptr is pointed at.
}
int main ()
{
int x = 20;
int * ptr = &a;
printf ("Before Change:%d", x); // 20
printf ("Before Change:%d", *ptr); // 20
changePointerValue (ptr);
printf ("After Change: %d\n", *ptr); // 10
printf ("After Change: %d\n", x); //10
}
Edit:
So, if you want it print 10 in the main function, the correct way to do this is deference ptr in the function. But this will also change the value of variable a in the main function.
int one(int ***ptr)
{
***ptr=10; // Dereference ptr to where it points to. (Varaible a in the main function)
return 32;
}
int main(int argc, char *argv[])
{
static int ***ptr;
int a=200,*b,**c;
int result;
b=&a;
c=&b;
ptr=&c;
printf("Main Ptr:%d\n",&ptr); // The memory address of variable ptr.
result=one(ptr);
printf("Main Ptr:%d\n",&ptr); // the memory address of variable ptr.
printf("Main Ptr:%d\n",***ptr); // 10
printf("Main a:%d\n", a); // 10
printf("Main result:%d\n", result); //32
system("PAUSE");
return 0;
}
You're setting ptr to the address-of-the-address-of-the-address-of a local variable (b), which goes out of scope at the end of the function. This is undefined behaviour. You either need to assign to ***ptr, or malloc something on the heap.
Also, you're passing ptr by value to the function. So any local modifications to it won't be reflected in main. You need to pass by pointer, i.e. you'll need an int **** as an argument.
I really hope this is nothing more than a learning exercise, because any more than two levels of pointers usually indicates that the design really needs to be re-evaluated!