tzload memory leak?

Guy Harris guy at auspex.com
Sat Apr 17 00:46:54 UTC 1993


> It has a memory leak which I think I've tracked down to tzload,
> which I call via tzset.

The data that's mallocated by the time zone stuff in SunOS 4.x is:

	the array of transition times;

	the array of information about the State Of The Time Zone after
	    a given transition time (offset from GMT, DST or not, index
	    into the list of time zone abbreviation strings, etc.);

	the array of time zone types (indices into the array of
	    information about the State Of The Time Zone after a given
	    transition time);

	the array of "char"s that contains the aforementioned
	    abbreviation strings.

Applications can't get a pointer to any of the first three items, so
they can be freed whenever "tzset()" is called.

However, it appears that the array containing abbreviation strings isn't
freed because, according to the comment, it "might have other references
to it", presumably obtained by using the "tzname[]" array (in the SV
environment) or by using the "tm_zone" member of "struct tm".

Now, from the way I read POSIX 1003.1, it neither commits to pointers
fetched from "tzname[]" remaining valid after a call to "tzset()", nor
explicitly claims that one should *not* assume they'll still point
somewhere valid.

The "ctime" manual page *does*, however, explicitly note that calls to
"tzset()" or "tzsetwall()" overwrite the array to which the "tm_zone"
field points.

So I'm not sure what provoked somebody to make "tzset()" *not* free up
the abbreviation-strings array - which is kind of annoying, given that
I'd be willing to bet I'm the person who made it not do so, and seem to
remember having done so because some stupid piece of software broke when
it *did* free it....

Unfortunately, the pointer to that array is in a structure pointed to by
a static pointer.

However, *if* you can call "localtime()" on a time that's known to be in
a time zone that corresponds to the first abbreviation in the file -
possibly easier said than done, although you might try passing it first
a pointer to a value of -1, and then a pointer to a value of "-1 plus
half a year", and then, for each of the times, if "localtime()" doesn't
return a null pointer, save the "tm_zone" values and, if both of them
are non-NULL, see which one is lower - you can try doing a "free()" on
the "tm_zone" value for that time zone.

This is a somewhat disgusting hack, but, well, that's life....



More information about the tz mailing list