Any process doesn't have a direct view of the physical memory as it would lead to unnecessary complications (eg: accessing other process' private data, accessing kernel memory etc). Basically, the OS doesn't trust the user with the actual physical memory and would like to manage everything on its own.
So, it's the job of the OS to virtualise the view of memory. It is one of the three primary tasks of an OS (the others being concurrency control and persistence.)
This has loads of advantages. Mainly, it makes the process feel that the entire memory is available to itself and this memory might be even more than the actual physical memory available. It also provides protection against process' accessing each other's parts and so on.
This is done mostly with the help of a mix of paging and segmentation in modern operating systems. The CPU generates a logical address, which is then converted into the physical address by the operating system. Every process has its own logical address space, in which it stores its data(code, heap, stack etc). This ensure protection, as well as the illusion of having a larger memory( as the logical address space can be much larger than the actual physical memory.)
When you say P1 is loaded at 10k, you are talking about the virtual address 10k. In fact, whatever address is visible to you use as a programmer, is a virtual address. When you do malloc() in C, it returns a virtual address.
Refer to sections on memory management from any standard OS textbook, you'd understand it.