> Can I call free with the argument ptr in main?

Yes.

> And what if I wrote the following...?

You would have a memory leak because you would have no way of freeing the memory at p.

> Does that mean I can no longer free the memory?

Yes. The memory would remain allocated and this is a memory leak.

> What if ...(complicated stuff I couldn't be bothered to decipher)

If you allocate memory, you MUST MUST MUST MUST keep the pointer given you by malloc. It doesn't matter where you keep it, you can keep it in p, copy it to x, write it to disk, punch it to paper tape, burn it onto the moon with a laser, anything you like, as long as when you're done with the memory you can retrieve the pointer and pass it to free. Then the memory will be correctly deallocated. It will NOT be correctly deallocated if you do not follow this very simple rule.

ptr=malloc(n) -> Keep the value in ptr.

free(ptr) -> ptr here must be the value returned by malloc.