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.