Living with Libraries
Some library functions for which source code is unavailable may gratuitously allocate and return buffers that contain their results, or require you to pass them buffers which they subsequently release. If you have source code for the library, by far the best approach is to simply install SMARTALLOC in it, particularly since this kind of ill-structured dynamic storage management is the source of so many storage leaks. Without source code, however, there’s no option but to provide a way to bypass SMARTALLOC for the buffers the library allocates and/or releases with the standard system functions.
For each function xxx redefined by SMARTALLOC, a corresponding routine
named “actuallyxxx
” is furnished which provides direct access to
the underlying system function, as follows:
Standard function |
Direct access function |
---|---|
|
|
|
|
|
|
|
|
For example, suppose there exists a system library function named
“getimage()
” which reads a raster image file and returns the address
of a buffer containing it. Since the library routine allocates the image
directly with malloc()
, you can’t use SMARTALLOC’s free()
, as
that call expects information placed in the buffer by SMARTALLOC’s
special version of malloc()
, and hence would report an error. To
release the buffer you should call actuallyfree()
, as in this code
fragment:
struct image *ibuf = getimage("ratpack.img");
display_on_screen(ibuf);
actuallyfree(ibuf);
Conversely, suppose we are to call a library function, “putimage()
”,
which writes an image buffer into a file and then releases the buffer
with free()
. Since the system free()
is being called, we can’t
pass a buffer allocated by SMARTALLOC’s allocation routines, as it
contains special information that the system free()
doesn’t expect
to be there. The following code uses actuallymalloc()
to obtain the
buffer passed to such a routine.
struct image *obuf =
(struct image *) actuallymalloc(sizeof(struct image));
dump_screen_to_image(obuf);
putimage("scrdump.img", obuf); /* putimage() releases obuf */
It’s unlikely you’ll need any of the “actually” calls except under very
odd circumstances (in four products and three years, I’ve only needed
them once), but they’re there for the rare occasions that demand them.
Don’t use them to subvert the error checking of SMARTALLOC; if you want
to disable orphaned buffer detection, use the sm_static(1)
mechanism
described above. That way you don’t forfeit all the other advantages of
SMARTALLOC as you do when using actuallymalloc()
and
actuallyfree()
.
See also
Possible Next Steps
Go back to Smart Memory Allocation.
Go back to Developer Guide.