Why 'life after free'.

James C Burley burley at world.std.com
Tue Oct 2 18:02:23 AEST 1990


In article <1990Sep30.163824.12974 at ibmpcug.co.uk> dylan at ibmpcug.co.uk (Matthew Farwell) writes:

   In article <quan.654673946 at sol> quan at sol.surv.utas.oz (Stephen Quan) writes:
   > From: wuxing at comp.mscs.mu.edu (Xing Wu)
   > >In article <quan.654410256 at sol> you write:
   > >>  tmp = (char *) malloc(100);
   > >>  for (i=0; i<=99 ; i++) *(tmp+i) = ch;
   > >>  free(tmp);
   > >>  return tmp;
   > I normally do what you suggest, the reason why a brought up this issue is
   > that if what I propose wasn't so unpredictable then I can have something
   > like :
   > 
   >   printf("%s\n",funny('c'));
   >   printf("%s\n",funny('x'));
   > 
   > Where funny will create a string of 100 c's or 100 s's.  The string is
   > displayed in 'printf' (hopefully) and you don't need to worry about
   > free-ing the memory.

   Forgive me if I'm wrong, but whats wrong with doing ....

   char *
   funny(c)
   char c;
   {
	   static char a[100];
	   int i;

	   for (i=0 ; i<99 ; i++) a[i] = c;
	   a[99] = '\0';
	   return (&a[0]);
   }

   Dylan.
   -- 
   Matthew J Farwell                 | Email: dylan at ibmpcug.co.uk
   The IBM PC User Group, PO Box 360,|        ...!uunet!ukc!ibmpcug!dylan
   Harrow HA1 4LQ England            | CONNECT - Usenet Access in the UK!!
   Phone: +44 81-863-1191            | Sun? Don't they make coffee machines?

It fails if you then do something like:

    printf("%s %s\n",funny('a'),funny('b'));

On the practical side, one might want to use a statement like the above
frequently as a debugging/testing feature in a program, where conciseness
and "lack of interference" with the surrounding production code is a must.
Yet the above statement (using two invocations of funny in one call, hence
overwriting the results of one call with the results of the other, in effect,
before invoking printf itself) might occur frequently.

So, if you need to have some function like "funny" that you expect to reside
in printf or similar calls, and there might be more than one, and you are
willing to "assert" to yourself that there are never more than, say, eight
(better yet, say MAX_PARALLEL_INVOCATIONS), then you can do something like:

   char *
   funny(c)
   char c;
   {
   #define MAX_PARALLEL_INVOCATIONS 8
	   static char a[MAX_PARALLEL_INVOCATIONS][100];
           static int cur = 0;
	   int i;
           char *ptr;

	   for (i=0 ; i<99 ; i++) a[cur][i] = c;
	   a[cur][99] = '\0';
	   ptr = &a[cur][0];
           if (++cur == MAX_PARALLEL_INVOCATIONS)
               cur = 0;  /* Wrap around to first area. */
           return ptr;
   }

This way you have enough static storage for 8 simultaneous ("parallel")
results of invoking funny() before results get effectively overwritten.
Define the value as large as you like.

I wouldn't recommend using this approach for production code (I mean
lines of code performing production duties) or anything other than small,
tight projects.  Use the "temp = funny(...); printf(...,temp,...); free(temp);"
solution outlined in another post (where funny doesn't free) for those.
The above approach, however, is useful as debug/test code because it doesn't
clutter up code with extra temps -- furthermore, the particular example
above adds no malloc/free sequences (except via invoking printf, perhaps),
which might make a buggy program a bit easier to debug.  (Remember, the best
debugger in the toughest situations is one that has the smallest impact on
its target environment, all else being equal; for that reason, I'd even
suggest using fputs(funny(...)); fputs(" ... "); fputs(funny(...)); and so on.
Debugging code should try to use the lowest-level stuff possible in case you
have to debug at a low level, as in checking for heap corruption and such.
But don't torture yourself and your debugging code to fit into this model;
if you're doing printfs to show how object states evolve during execution or
other such higher-level things, then just make sure you can turn them all of
easily via #define if you do run into a low-level bug.)

James Craig Burley, Software Craftsperson    burley at world.std.com



More information about the Comp.lang.c mailing list