Clever said:
Wouldn't interpositioning allow you to define a default global symbol
"malloc" that would essentially overwrite the Standard one?
Not, mind you, something I recommend, but isn't one of the hallmarks of
C that one can do this without constraint, making all code (including
any external libs that are linked in later) use the non-standard function?
"Hallmark of C ..." Fuzzy concept, that. Yet the Rationale
invokes the "Spirit of C," so perhaps we can dither a bit without
risk of too much castigation.
In my own (less than universal) experience, two obstacles to
interposing your own malloc() -- or sqrt(), or whatever -- are
fairly frequently found:
- The Standard library may be incorporated into the program
as an indivisible unit: You get the whole thing, or nothing
at all. This is/was the case on VMS in the Old Days, when
the whole schmear was implemented as one giant monolithic
shared library. VMS' linker would squawk about conflicting
symbol definitions if your home-grown malloc() had the same
name as the malloc() in the library.
- The library itself may use unadvertised knowledge of its own
internals. (It pretty much must do so if things like atexit()
and fflush(NULL) are to work.) For example, imagine an fopen()
that for performance reasons wants to allocate an I/O buffer
on a memory page boundary. It might call a library-private
_malloc_pages() function to get such specially-aligned memory.
Fine so far: You haven't replaced _malloc_pages(), so the
library's own version is used. But what if fopen() then hands
the buffer memory to free()? It's (presumably) your free(),
not the library's free(), that gets called -- and what are
the chances that your free() and the library's free() use
identical data structures?
It's a shame, really, that C doesn't have a mechanism to allow
overriding parts of the library. Because abuses of dynamic memory
are so common, the malloc() suite is perhaps the most mouth-watering
override target, but there are others: A gets() that bleats whenever
called, or a scanf() that complains if given a "%s", even an acos()
that dumps a stack trace if its argument is larger than 1. The C
Standard, though, makes a point of separating the roles of implementor
and user -- and having lived on both sides of that fence, I for one
find the fence something of a comfort.