1) "Deleting" a pointer causes it's destructor to be called (if any) and then relinquishes ownership of that chunk of memory back to the system to be used elsewhere. So the pointer itself is still going to contain that memory address. If you then try to dereference the pointer things may seem to work normally for a while or the program may well crash at any point. Setting it to NULL ensures that an error will be raised the moment you try to dereference the invalid pointer.
2) Just as you have it: "delete p_int;". For an array you would use the "delete[] p_int;".
3) No, the implementation is free to dole it out however it likes.
4) It sounds like you're asking if an allocated chunk should have at least one pointer attached to it? If so, yes, because otherwise you'd have a memory leak.
5) Absolutely! Just don't "delete" something that hasn't been allocated with "new".
Oh, and once you understand how pointers work, be sure to study up on the principles of RAII...