It would be clearer if you gave the variables in different functions different names. Since you have multiple variables and arguments named p, and they are distinct from each other, it is easy to confuse yourself.
void alloc2(int** pa2)
{
*pa2 = (int*)malloc(sizeof(int));
**pa2 = 10;
}
void alloc1(int* pa1)
{
pa1 = (int*)malloc(sizeof(int));
*pa1 = 10;
}
int main()
{
int *p = 0;
alloc1(p);
//printf("%d ",*p);//value is undefined
alloc2(&p);
printf("%d ",*p);//will print 10
free(p);
return 0;
}
Apart from renaming the arguments of functions, I've also initialised p in main() to zero (the NULL pointer). You had it uninitialised, which means that even accessing its value (to pass it to alloc1()) gives undefined behaviour.
With p being NULL, alloc1() also receives the NULL pointer as the value of pa1. This is a local copy of the value of p from main(). The malloc() call then changes the value of pa1 (and has no effect on p in main(), since it is a different variable). The statement *pa1 = 10 sets the malloced int to be 10. Since pa1 is local to alloc1() it ceases to exist when alloc1() returns. The memory returned by malloc() is not free()d though (pa1 ceases to exist, but what it points to doesn't) so the result is a memory leak. When control passes back to main(), the value of p is still zero (NULL).
The call of alloc2() is different, since main() passes the address of p. That is the value of pa2 in alloc2(). The *pa2 = (int *)malloc(sizeof(int)) statement does change the value of p in main() - to be the value returned by malloc(). The statement **pa2 = 10 then changes that dynamically allocated int to be 10.
Note also that the (int *) on the result of malloc() is unnecessary in C. If you need it, it means one of
- You have not done
#include <stdlib.h>. The type conversion forces the code to compile, but any usage of the int - strictly speaking - gives undefined behaviour. If this is the case, remove the int * and add #include <stdlib.h>.
- You are compiling your C code using a C++ compiler.