Re: NEVER USE return str_dup(s); !!!

From: Paul Cole (pcole@ccwf.cc.utexas.edu)
Date: 09/15/95


On Fri, 15 Sep 1995, Scatter wrote:

> > > Maybe str_dup()? (its defined in utils.c)
> > 
> > Don't even think about doing that !!!!!!!!!!!!
> > This is the classical example of a memory leak !
> > 
> > Everytime you pass this point you will have some bytes of
> > memory less and some garbage more in memory until you crash.
> >
> 
> Excerpt from a man page follows:
> ------------------------------------------------------------------------ 
[man page snipped]
> 
> 
> 
> How on earth does returning a strdup create a memory leak?  If value
> is freed when your done with it, there is no leak.  This call seems to 
> be just an enhanced malloc....
> 
> 
> Not being argumentative, I just don't understand.


Its good that you read the man page.  

[no offense intended, no flames desired]

I think the point was that it is clear not everyone on this list truely
understands what they are doing, read the man pages and/or understand
them.  Thus the use of any feature that allocates memory is a potential
memory leak to these people since they may not realize the importance of
being absolutely sure that the memory allocated is indeed free'd at some
point down the line. 

The static method removes the need to free the memory at all, doing so
would be an error in itself. Although it does, as was posted in a previous
message, increase the overall runtime size of the application, at least it
doesn't create a potential and every growing leak with every call to the 
strdup/str_dup function.

Therefor for those who aren't sure what they are doing, the static method 
ensures that they won't create a run-away memory hog.

Wasn't that the point you were trying to make Thomas?

-------------
HOWEVER!
a static variable has its own unique behavior that can cuase problems.

Example..

----------------

/* static.c  by Paul Cole
 * Purpose:  Demonstrate caveat of using static buffers
 *           in conjunction with assignments to persistent variables.
 */

/* char *foo()
 * returns a static string buffer with
 *  "value1" on the first call 
 *  "value2" on all other calls
 */
char * foo()
{
   static int inited = 0;
   static char buf[10];

   if (inited)
   {
      strcpy(buf, "value2");
      return buf;
   }
   
   strcpy(buf, "value1");
   inited = 1;
   return buf;
}

/* int main()
 * Purpose: use foo() to create two results and watch the values.
 */
int main()
{
   char *value1;
   char *value2;
  
   /* value1 and value2 are undefined at first */

   value1 = foo();
   puts("after first call...\n");
   printf("value1 = %s\n", value1);
   puts("value2 is undefined.\n");  /* value2 is still undefined */
   puts("\n");

   value2 = foo();
   puts("after second call...\n");
   printf("value1 = %s\n", value1);
   printf("value2 = %s\n", value2);
   /* both values are now valid but point to the same address, foo():buf */
   puts("\n");

   return 0
}

-------------------------

Runninng this example yields...

=================

> ./static
after first call...

value1 = value1
value2 is undefined.



after second call...

value1 = value2
value2 = value2

=================

Notice that although the result of foo() was assigned to two different 
variables, both variables assumed the same value on the second call.
This is because they both shared the same memory address, the static 
buffer in foo().

Why is this important?  Becuase as I understand it, the original post on 
this topic was asking why are global buffered used to often in circle 
functions when that makes the function non-reentrant.  Then the use of 
static variables was proposed, but as i've demonstrated, they are still 
not reentrant.  Assignments to static variables, like globals, clobber 
the previous results.

Moral?  Be aware of the limits and benefits of each method and use the 
appropriately, none are the end-all be-all solution.

What do I use statics for?

I use statics to preserve values of local variables thruogh function 
calls so I can have different behavior depending on how many times the 
function has been called for example.  Note the static int inited=0 in 
foo().

  --Paul



This archive was generated by hypermail 2b30 : 12/07/00 PST