Bug 12540 - Memory leak in locale::locale(const char*)
Memory leak in locale::locale(const char*)
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: libstdc++
3.4.0
: P2 normal
: 3.3.3
Assigned To: Paolo Carlini
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2003-10-08 12:22 UTC by Pétur Runólfsson
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Test case (1.52 KB, text/plain)
2003-10-08 12:25 UTC, Pétur Runólfsson
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pétur Runólfsson 2003-10-08 12:22:04 UTC
There is a memory leak in the constructor locale::locale(const char*).
The string allocated with strdup in the following snippet is leaked
under some conditions.

                // LANG may set a default different from "C".
                char* __env = std::getenv("LANG");
                if (!__env || std::strcmp(__env, "") == 0 
                    || std::strcmp(__env, "C") == 0 
                    || std::strcmp(__env, "POSIX") == 0)
                  __res = strdup("C");
                else 
                  __res = strdup(__env);

[...]

                      }
                    __str.erase(__str.end() - 1);
                    _M_impl = new _Impl(__str.c_str(), 1);
                  }
                // ... otherwise either an additional instance of
                // the "C" locale or LANG.
                else if (std::strcmp(__res, "C") == 0)
                  (_M_impl = _S_classic)->_M_add_reference();
                else
                  _M_impl = new _Impl(__res, 1);
                std::free(__res);

The leak occurs if the calls to locale::_Impl::_Impl throws an exception,
in that case free isn't called.
Comment 1 Pétur Runólfsson 2003-10-08 12:25:02 UTC
Created attachment 4901 [details]
Test case

This is the test case from PR 12352. Note that it leaks very slowly,
so a large value of iters must used to detect it.
Comment 2 Pétur Runólfsson 2003-10-08 12:26:27 UTC
Also note that to get the leak, LC_ALL must not be set in the environment
and LANG must not be C.
Comment 3 Paolo Carlini 2003-10-08 13:08:47 UTC
Ok, thanks. I had already noticed that more work was needed in this area...
probably this is *not* the last problem, unfortunately.
Comment 4 CVS Commits 2003-10-16 17:24:11 UTC
Subject: Bug 12540

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	paolo@gcc.gnu.org	2003-10-16 17:24:07

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/src: locale.cc 
	libstdc++-v3/config/locale/gnu: monetary_members.cc 

Log message:
	2003-10-16  Paolo Carlini  <pcarlini@suse.de>
	
	PR libstdc++/12540
	* config/locale/gnu/monetary_members.cc
	(moneypunct<wchar_t, true/false>::_M_initialize_moneypunct):
	Don't leak memory if new throws.
	* src/locale.cc (locale::locale(const char*)): In order not
	to leak memory in case new throws, use a basic_string type
	for __res too and avoid strdup.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2015&r2=1.2016
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/src/locale.cc.diff?cvsroot=gcc&r1=1.97&r2=1.98
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/config/locale/gnu/monetary_members.cc.diff?cvsroot=gcc&r1=1.11&r2=1.12

Comment 5 Paolo Carlini 2003-10-16 17:59:46 UTC
Fixed for 3.4.