This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] Fix exception unsafety of __numpunt_cache
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: Paolo Carlini <pcarlini at suse dot de>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>, Benjamin Kosnik <bkoz at redhat dot com>
- Date: Mon, 24 Nov 2003 13:21:48 +0100
- Subject: Re: [Patch] Fix exception unsafety of __numpunt_cache
- References: <3FC156EA.5020608@suse.de>
... I like *much* more the version below: we early set _M_allocated in
__numpunct_cache<_CharT>::_M_cache, in this way if any of the new
throws, then catched by __use_cache<>::operator(), the memory is
automatically freed by __numpunct_cache<>::~__numpunct_cache: very
clean!
Tested x86-linux.
Again, OK with you, Benjamin?
Paolo.
///////////
2003-11-24 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.h
(__numpunct_cache<>::_M_cache): Set _M_allocated at the beginning in
order to avoid memory leaks; simplify a bit.
diff -prN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
*** libstdc++-v3-orig/include/bits/locale_facets.h Tue Nov 4 03:06:59 2003
--- libstdc++-v3/include/bits/locale_facets.h Mon Nov 24 13:10:38 2003
*************** namespace std
*** 647,678 ****
void
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- string __grouping = __np.grouping();
- char* __group = new char[__grouping.length() + 1];
- __grouping.copy(__group, __grouping.length());
- __group[__grouping.length()] = char();
- _M_grouping = __group;
-
- _M_use_grouping = __grouping.length() != 0 && __grouping.data()[0] != 0;
! typedef basic_string<_CharT> __string_type;
! __string_type __true = __np.truename();
! _CharT* __truename = new _CharT[__true.length() + 1];
! __true.copy(__truename, __true.length());
! __truename[__true.length()] = _CharT();
_M_truename = __truename;
!
! __string_type __false = __np.falsename();
! _CharT* __falsename = new _CharT[__false.length() + 1];
! __false.copy(__falsename, __false.length());
! __falsename[__false.length()] = _CharT();
_M_falsename = __falsename;
!
_M_decimal_point = __np.decimal_point();
_M_thousands_sep = __np.thousands_sep();
!
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(__num_base::_S_atoms_out,
__num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
--- 647,681 ----
void
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
+ _M_allocated = true;
+ _M_grouping = NULL;
+ _M_truename = _M_falsename = NULL;
+
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
! const string::size_type __len = __np.grouping().size();
! char* __grouping = new char[__len + 1];
! __np.grouping().copy(__grouping, __len);
! __grouping[__len] = char();
! _M_grouping = __grouping;
! _M_use_grouping = __len && __np.grouping()[0] != 0;
! typedef basic_string<_CharT> __string_type;
! typename __string_type::size_type __lentf = __np.truename().size();
! _CharT* __truename = new _CharT[__lentf + 1];
! __np.truename().copy(__truename, __lentf);
! __truename[__lentf] = _CharT();
_M_truename = __truename;
!
! __lentf = __np.falsename().size();
! _CharT* __falsename = new _CharT[__lentf + 1];
! __np.falsename().copy(__falsename, __lentf);
! __falsename[__lentf] = _CharT();
_M_falsename = __falsename;
!
_M_decimal_point = __np.decimal_point();
_M_thousands_sep = __np.thousands_sep();
!
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(__num_base::_S_atoms_out,
__num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
*************** namespace std
*** 680,687 ****
__ct.widen(__num_base::_S_atoms_in,
__num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
_M_atoms_in[__num_base::_S_iend] = _CharT();
-
- _M_allocated = true;
}
template<typename _CharT>
--- 683,688 ----