best way to return (char *)

Kevin Watts kevin at claris.com
Sun Jun 25 08:33:39 AEST 1989


>From article <1989Jun23.170749.23253 at utzoo.uucp>, by henry at utzoo.uucp (Henry Spencer):
> If you want to combine high speed and unbounded returned values and are
> willing to commit unspeakable acts to do it :-), have the caller pass in
> a buffer (and its size!) which is *usually* big enough, and have the
> function return either that buffer or (if it's not large enough) malloced
> memory.  This avoids the malloc overhead most of the time and still lets
> values be of unlimited size.  It's definitely a nuisance to manage, though.

A similar approach, used by Apple in their upcoming GS/OS is as follows:
On input, pass a buffer with its length (including the space for the length)
in the first word (one could use a long instead).  If the buffer is large
enough, the routine uses it, otherwise the routine returns an error code and
puts the size of the buffer it needs into the _second_ word of the buffer.
The caller is supposed to allocate a buffer of that size and call the routine
again, thus:
	char buffer[20];
	*(int *) buffer = 20;
	int size;

	if (the_routine(buffer) = ERROR) {
		size = *(int *)(buffer+2);
		new_buffer = malloc(size); /* should check for error here */
		*(int *) buffer = size;
		the_routine(new_buffer);
	}
I'm not convinced that this is a clean solution, but it does keep the memory
allocation all at the same level and will work for any size (up to 64K in this
case).


My preference is to use C++ which allows safe allocation and deallocation at
different levels, but this is the wrong group for that.

The other alternative which comes to mind is to use a garbage collector.
-- 
 Kevin Watts        ! Any opinions expressed here are my own, and are not
 Claris Corporation ! neccessarily shared by anyone else.  Unless they are
 kevin at claris.com   ! patently absurd, in which case they're not mine either.



More information about the Comp.lang.c mailing list