Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!world!burley From: burley@world.std.com (James C Burley) Newsgroups: comp.lang.c Subject: Re: Why 'life after free'. Message-ID: Date: 2 Oct 90 08:02:23 GMT References: <1990Sep30.163824.12974@ibmpcug.co.uk> Sender: burley@world.std.com (James C Burley) Distribution: comp Organization: The World Lines: 98 In-Reply-To: dylan@ibmpcug.co.uk's message of 30 Sep 90 16:38:24 GMT In article <1990Sep30.163824.12974@ibmpcug.co.uk> dylan@ibmpcug.co.uk (Matthew Farwell) writes: In article quan@sol.surv.utas.oz (Stephen Quan) writes: > From: wuxing@comp.mscs.mu.edu (Xing Wu) > >In article 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@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@world.std.com