By declaring int * foo you've only created a pointer. foo is not actually pointing at anything yet - it's uninitialised. You might even get a segmentation fault from code like that, as the pointer could point outside of program memory. If you do:
int * foo = (int *)malloc(sizeof(int));
You will have initialised the pointer, malloc allocates some memory from the heap of the size passed to it. You can also do:
int bar = 0;
int * foo = &bar;
Which will make foo a pointer to bar (& returns the address of the variable).