Just remember "declaration follows usage".
If you have the declaration
in the usage ptr, it is a pointer to int; the usage *ptr, it is an int;
So, having as in your example: int *numPtr; we need
numPtr = malloc(sizeof (int)); /* numPtr is a pointer, which is right for the return value of malloc() */
PtrPtr = numPtr; /* numPtr is a pointer, which is the same type as PtrPtr */
*numPtr = 42; /* assign the int 42 to a memory location that can hold ints */
printf("%i\n", *numPtr); /* *numPtr is an int */