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.
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.
Also note that to get the leak, LC_ALL must not be set in the environment and LANG must not be C.
Ok, thanks. I had already noticed that more work was needed in this area... probably this is *not* the last problem, unfortunately.
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
Fixed for 3.4.