locale::_Impl::_Impl and exceptions
Kevin Ediger
kediger@licor.com
Mon Nov 15 10:35:00 GMT 1999
Hello,
The constructors for locale::__Impl
don't look correct to me. There are some try...catch handlers that
probably were intended to prevent memory leaks, but they don't do
that and I think a core dump is inevitable if an exception does
occur; the code deletes _M_facets and _M_category_names when the
compiler should have already taken care of that.
Here's a patch that uses auto_ptr to make the constructors exception
safe.
Best Regards,
Kevin Ediger
Index: src/locale.cc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/src/locale.cc,v
retrieving revision 1.30
diff -u -p -r1.30 locale.cc
--- locale.cc 1999/08/26 08:51:15 1.30
+++ locale.cc 1999/11/15 18:19:51
@@ -36,6 +36,7 @@
#include <bits/std_istream.h>
#include <bits/std_ostream.h>
#include <bits/std_vector.h>
+#include <bits/std_memory.h> // for auto_ptr
namespace std {
@@ -51,58 +52,46 @@ namespace std {
locale::_Impl::_Impl(size_t __numfacets, size_t __refs)
: _M_num_references(__refs - 1)
- // , _M_facets (numfacets, (facet*)0)
- // , _M_category_names (_S_num_categories, string ("*"))
+ , _M_facets (0)
+ , _M_category_names (0)
, _M_has_name(false)
, _M_cached_name_ok(false)
, _M_cached_name(string ("*"))
{
typedef vector<facet*, __STL_DEFAULT_ALLOCATOR(facet*) > __vec_facet;
typedef vector<string, __STL_DEFAULT_ALLOCATOR(string) > __vec_string;
- try {
- _M_facets = new __vec_facet(__numfacets, (facet*)0);
- }
- catch (...) {
- delete _M_facets;
- throw;
- }
- try {
- _M_category_names = new __vec_string(_S_num_categories, string("*"));
- }
- catch (...) {
- delete _M_category_names;
- throw;
- }
+
+ auto_ptr<__vec_facet> __pvf(new __vec_facet(__numfacets,(facet*)0));
+ auto_ptr<__vec_string> __pcn(new __vec_string(_S_num_categories,string("*")));
+ _M_facets = __pvf.release();
+ _M_category_names = __pcn.release();
}
locale::_Impl::_Impl(const _Impl& __other, size_t __refs)
: _M_num_references(__refs)
- // , _M_facets (other._M_facets)
- // , _M_category_names (other._M_category_names)
+ , _M_facets (0)
+ , _M_category_names (0)
, _M_has_name(__other._M_has_name)
, _M_cached_name_ok(__other._M_cached_name_ok)
, _M_cached_name(__other._M_cached_name)
{
typedef vector<facet*, __STL_DEFAULT_ALLOCATOR(facet*) > __vec_facet;
typedef vector<string, __STL_DEFAULT_ALLOCATOR(string) > __vec_string;
- try {
- _M_facets = new __vec_facet(*(__other._M_facets));
- }
- catch (...) {
- delete _M_facets;
- throw;
- }
- try {
- _M_category_names = new __vec_string(*(__other._M_category_names));
- }
- catch (...) {
- delete _M_category_names;
- throw;
- }
+
+ auto_ptr<__vec_facet> __pvf(new __vec_facet(*(__other._M_facets)));
+ auto_ptr<__vec_string> __pcn(new __vec_string(*(__other._M_category_names)));
- std::vector<facet*>::iterator __it = _M_facets->begin();
- for (; __it != _M_facets->end(); ++__it)
+ std::vector<facet*>::iterator __it = __pvf->begin();
+ for (; __it != __pvf->end(); ++__it)
(*__it)->_M_add_reference();
+
+ /*
+ * these must be last since in the presence of an exception, the destructor
+ * for this won't run until AFTER execution has passed the closing brace
+ * of the constructor
+ */
+ _M_facets = __pvf.release();
+ _M_category_names = __pcn.release();
}
void
===================================================================
--
LI-COR, Inc.
Voice: 402.467.3576 ext 3695, Fax: 402.467.0872
mailto:kediger@licor.com
http://www.licor.com
More information about the Libstdc++
mailing list