Using environment variables without leaking memory?

Rich Felker dalias at aerifal.cx
Mon Oct 23 09:28:07 UTC 2006


On Sun, Oct 22, 2006 at 09:08:58PM -0400, Rob Landley wrote:
> Maybe this is the wrong place to ask, but the fundamental problem is that the 
> libc API is badly designed.  I assume uClibc does this right, so you guys 
> must know:
> 
> How do I set (and reset) environment variables without leaking memory?  I 
> _think_ if I use setenv() instead of putenv() it won't leak memory (freeing 
> the old one), but if I previously used putenv() and then call setenv() to 
> update that variable, does it free the old chunk of memory?  Or not?  (How 
> does it know?  Presumably the environment variables inherited from a parent 
> process weren't allocated with malloc()...)

putenv has no requirement about where the memory came from (no reason
to believe it should be malloc'd; it could be static/const or
anything!) so there's no hope of it being automatically freed. You can
free it yourself though if you keep track of it. setenv _should_ free
the memory it allocates, but popular implementations (glibc) do not.

The only portable way to avoid leaking memory is to declare
"extern char **environ;" and manage the environment yourself.

> I'm missing a concept here, I think.  I don't quite understand all the details 
> of environment variables.  With putenv() you take a malloced chunk of memory 
> and it becomes a live environment variable,

Not necessarily malloc; it could come from anywhere.

> but how does a child process 
> inherit that sucker when exec a new process and free all the old memory?

If you're only worried about exec, there is no mem leak issue at all.
On exec, the kernel obtains a copy of the environment, repacks it and
places it on the top of the stack of the new process image, and passes
the pointer to the start code for the new process image. Malloc'd
memory does not persist across exec anyway.

Rich




More information about the uClibc mailing list