In article <pa****************************@gmail.com>,
Robert Gamble <rg*******@gmail.com> wrote:
I can come up with two interpretations here.
The first is: "Why can't we dereference pointers that point to memory that
has been freed since there is no garbage collection system to re-use the
memory?"
My answer to the former would be: Because the Standard says so. Some
implementations may, for example, return memory back to the operating
system. In any case, no guarantees are made by the Standard regarding the
free'd memory except that attempting to access it invokes undefined
behavior.
Adding a bit to that:
a) Having a garbage collection system of some sort is perfectly valid
and fairly common.
b) It is common for the memory allocator to use the space occupied by
the freed memory in order to store information needed by the allocator.
For example, the allocator might store the address of the next free
chunk of memory, so that it can chase through the list in order to find
available memory;
c) The C standard only allows C programmers to access within objects,
and once memory is freed it is no longer part of an object; thus
accessing that memory will have undefined results;
d) For the -typical- C allocator, returning memory back to the
operating system is fairly unusual, as it typically is too much overhead
to figure out whether there might be memory further along that is still
in use; this fits in with the traditional Unix "memory growth is
always after the last allocated memory" paradigm.
e) It is acceptable behaviour within the standard for
the memory allocator to allocate in distinct virtual memory "pages" and to
keep track of the use of the page, and to return the virtual page to
the operating system when the page is no longer in use. This may
result in holes in the logical address space, but that's irrelevant
because the standard places tight constraints on accessing outside of
valid existing objects. This has been implemented on real systems.
There are advantages and disadvantages to each of (d) and (e).
f) On some real systems (e.g., the DEC VAX), each "pointer" is
not just an address but a key to a memory descriptor, with hardware
or software protection that -prevents- you from accessing out of bounds.
When you have freed a pointer, the memory descriptor may thereafter
be garbage or may be specifically set to a descriptor that will cause
a fault.
g) Keep in mind that a pointer is not necessarily a number as such.
You should not think of it as strictly a byte (or word) count from the
beginning of RAM. A pointer may be a semi-opaque value with no inherent
meaning, with a look-up table of some sort determining what the
pointer refers to. If you look at what you can legally do with
pointers, you will find that it is even possible for "the same pointer"
to refer to different parts of memory in different code sections -- so
once you have free()'d a pointer, there is no certainty at all about
-what- it refers to!
--
"[...] it's all part of one's right to be publicly stupid." -- Dave Smey