T
Tim Rentsch
Keith Thompson said:I've used a variant of this. I had a function returning char* that
declared two local static variables, an array of arrays of char (for
the results), and an index. On each call, it would cycle the index
through the array and use a fresh sub-array for the result. This
allowed, say, half a dozen distinct calls to be active simultaneously.
It's not pretty, and it still forces you to decide in advance both how
big the result can be and how many distinct results you need, but it's
a bit more flexible than using a single static array.
A single function can do this for lots of other functions:
const char *
semi_permanent_copy( const char * s ){
static char buffer[ SOME_SIZE ];
static size_t next = 0;
size_t needed;
if( s == NULL ) return NULL; /* a plausible choice */
if( (needed = strlen(s) + 1) > SOME_SIZE ) die( "no space" );
if( needed > SOME_SIZE - next ) next = 0;
next += needed;
memcpy( & buffer[ next - needed ], s, needed );
return & buffer[ next - needed ];
}
Client functions would have their own local (auto) buffers, and use
return semi_permanent_copy( local_buffer );
to return "semi-permanent" results.
Allocating out of a single buffer means there can be more strings if
they are shorter, or longer strings if there aren't as many. Also,
with all the clients sharing a single buffer, it's easier to feel good
about having a generously sized buffer, which will reduce the chance
of exceeding a fixed limit.
The return type being 'const' helps make sure strings in the buffer
aren't mistakenly overwritten, and increases the likelihood that the
results won't be held on to for too long. If a non-const version is
desired, just wrap one function around another:
char *
semi_permanent_writeable_copy( const char *s ){
... as above ...
}
const char *
semi_permanent_copy( const char *s ){
return semi_permanent_writeable_copy( s );
}
Following what I think is good practice, the safer version has the
shorter, easier name. Strictly speaking, the second function here
isn't necessary, because return results that are 'const' will
automatically convert if the writeable version is used. But having
the safer 'const' version be the default increases the chance that
clients will make conscious and considered decisions and use the
writeable version only where really necessary.
Disclaimer: I've used code much like this, but what's here is just
typed in, not compiled or tested.