A pointer contains the address of some other variable. Usually, a pointer only takes up a byte in memory. There are problems with letting the programmer explicitly mess around with the memory. Using free can cause dangling pointers . If we then try to use p to get to x, we can run into serious run-time errors, because x no longer exists, and p points to whatever now occupies that chunk of memory.
Some languages disallow the user to explicitly deal with memory.
This is neccessary because dynamic data structures can grow to be very large, and we can run out of memory. When new is executed, the memory allocation routines look on the free list for memory chunks that are not being used. If there are none available, then garbage collection routines are called to free up some memory. Live objects are those that are being used by the running program. In programs that continuously run, memory leaks can be slow and cumulative, so that they cause the program to crash after years of running with no problems.