
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Stephen Torri Sent: 16 May 2007 23:52 To: boost-users Subject: [Boost-users] Best way to create a class using the singletonpattern and shared pointers?
Here is a function that I am trying to understand why its giving me a error via valgrind of "Invalid read of size 4".
16: Trace_State::ptr_t Trace_State::Instance() 17: { 18: // Lock the resource? 19: if ( m_instance.get() == 0 ) 20: { 21: m_instance = Trace_State::ptr_t ( new Trace_State() ); 22: } 23: 24: // Unlock the resource? 25: 26: return m_instance; 27: }
When I look at the full error report I see:
==10721== Invalid read of size 4 ==10721== at 0x41682E3: boost::detail::atomic_increment(int*) (sp_counted_base_gcc_x86.hpp:66) ==10721== by 0x4168359: boost::detail::sp_counted_base::add_ref_copy() (sp_counted_base_gcc_x86.hpp:133) ==10721== by 0x41684B1: boost::detail::shared_count::shared_count(boost::detail::share d_count const&) (shared_count.hpp:170) ==10721== by 0x41775CF: boost::shared_ptr<libreverse::trace::Trace_State>::shared_ptr( boost::shared_ptr<libreverse::trace::Trace_State> const&) (shared_ptr.hpp:106) ==10721== by 0x41772F0: libreverse::trace::Trace_State::Instance() (Trace.cpp:26) ==10721== by 0x417731B: libreverse::trace::Trace::write_Trace(unsigned, std::string) (Trace.cpp:180) ==10721== by 0x425E394: libreverse::elf_module::Elf_Reader<32>::~Elf_Reader() (Elf_Reader_T.cpp:52) ==10721== by 0x423C8FD: void boost::checked_delete<libreverse::elf_module::Elf_Reader<32>
(libreverse::elf_module::Elf_Reader<32>*) (checked_delete.hpp:34) ==10721== by 0x42480B8: boost::detail::sp_counted_impl_p<libreverse::elf_module::Elf_R eader<32> >::dispose() (sp_counted_impl.hpp:76) ==10721== by 0x804C207: boost::detail::sp_counted_base::release() (sp_counted_base_gcc_x86.hpp:145) ==10721== by 0x804C231: boost::detail::shared_count::~shared_count() (shared_count.hpp:159) ==10721== by 0x423C171: boost::shared_ptr<libreverse::io::File_Reader>::~shared_ptr() (shared_ptr.hpp:106) ==10721== Address 0x43F7A44 is 12 bytes inside a block of size 24 free'd ==10721== at 0x40050FF: free (vg_replace_malloc.c:233) ==10721== by 0x4185AC5: operator delete(void*) (sp_debug_hooks.cpp:205) ==10721== by 0x417C9A4: boost::detail::sp_counted_impl_p<libreverse::trace::Trace_Stat e>::~sp_counted_impl_p() (sp_counted_impl.hpp:52) ==10721== by 0x4168337: boost::detail::sp_counted_base::destroy() (sp_counted_base_gcc_x86.hpp:126) ==10721== by 0x804C1CD: boost::detail::sp_counted_base::weak_release() (sp_counted_base_gcc_x86.hpp:159) ==10721== by 0x804C212: boost::detail::sp_counted_base::release() (sp_counted_base_gcc_x86.hpp:146) ==10721== by 0x804C231: boost::detail::shared_count::~shared_count() (shared_count.hpp:159) ==10721== by 0x4168EBB: boost::shared_ptr<libreverse::trace::Trace_State>::~shared_ptr () (shared_ptr.hpp:106) ==10721== by 0x4176711: __tcf_1 (Trace.cpp:14) ==10721== by 0x47BDCBE8: __cxa_finalize (in /lib/libc-2.5.so) ==10721== by 0x4167192: (within /usr/local/lib/libreverse.so.0.0.0) ==10721== by 0x429EE3B: (within /usr/local/lib/libreverse.so.0.0.0) ==10721==
The error is coming when the return of the Trace boost shared ptr. I am wondering if I have made an error in the creation of the class. Here is how the class is defined:
#ifndef LIBREVERSE_TRACE_H #define LIBREVERSE_TRACE_H
#include <boost/cstdint.hpp> #include <boost/shared_ptr.hpp> #include <fstream> #include "Reverse.h"
namespace libreverse { namespace trace {
/* Idea taken from http://www.codeproject.com/debug/xytrace.asp * (28 Jan 2002 - Xiangyang Liu) * * I have modified this so that we don't use varargs and use constant types */ class Trace_State { public:
typedef boost::shared_ptr<Trace_State> ptr_t;
virtual ~Trace_State();
static Trace_State::ptr_t Instance();
void set_Trace_File_Prefix ( std::string name );
void set_Trace_Level ( boost::uint32_t level );
void open_Trace_File ( void );
std::string get_ID_String ( void );
void close_Trace_File ( void );
boost::uint32_t get_Trace_Level ( void ) const;
void write_Message ( boost::uint32_t level, std::string msg );
private:
Trace_State();
static Trace_State::ptr_t m_instance;
std::string m_file_prefix;
boost::uint32_t m_trace_level;
//boost::recursive_mutex m_mutex;
std::ofstream m_log_stream; };
class Trace { public:
static bool write_Trace ( boost::uint32_t level, std::string message ); };
} /* namespace trace */ } /* namespace libreverse */
#endif /* LIBREVERSE_TRACE_H */
Is this an appropriate way to create a class using the singleton pattern? Is the constructor assigning the boost shared_ptr?
Stephen
Sorry, I don't have an answer to your specific question, but why would you need to use a shared_ptr on a singleton anyway? You have no real need to deallocate a singleton instance, so no need for a shared_ptr....perhaps use a reference (See Meyers singletons) Oh, hold on a sec....is it valid to call get() on an unassigned shared_ptr, which you are doing in the instance function? James
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.