Fixed memory leaks found by Valgrind

v0.27.3
Andreas Huggel 20 years ago
parent 50abec1639
commit 9c20ef1edb

@ -114,6 +114,18 @@ namespace Action {
return *instance_; return *instance_;
} // TaskFactory::instance } // TaskFactory::instance
void TaskFactory::cleanup()
{
if (instance_ != 0) {
Registry::iterator e = registry_.end();
for (Registry::iterator i = registry_.begin(); i != e; ++i) {
delete i->second;
}
delete instance_;
instance_ = 0;
}
} //TaskFactory::cleanup
void TaskFactory::registerTask(TaskType type, Task::AutoPtr task) void TaskFactory::registerTask(TaskType type, Task::AutoPtr task)
{ {
Registry::iterator i = registry_.find(type); Registry::iterator i = registry_.find(type);

@ -107,6 +107,8 @@ namespace Action {
this method. this method.
*/ */
static TaskFactory& instance(); static TaskFactory& instance();
//! Destructor
void cleanup();
/*! /*!
@brief Create a task. @brief Create a task.

@ -142,6 +142,10 @@ int main(int argc, char* const argv[])
} }
task->run(*i); task->run(*i);
} }
taskFactory.cleanup();
params.cleanup();
return 0; return 0;
} // main } // main
@ -157,6 +161,12 @@ Params& Params::instance()
return *instance_; return *instance_;
} }
void Params::cleanup()
{
delete instance_;
instance_ = 0;
}
void Params::version(std::ostream& os) const void Params::version(std::ostream& os) const
{ {
os << EXV_PACKAGE_STRING << ", " os << EXV_PACKAGE_STRING << ", "

@ -119,6 +119,8 @@ public:
@return Reference to the global Params instance. @return Reference to the global Params instance.
*/ */
static Params& instance(); static Params& instance();
//! Destructor
void cleanup();
//! Enumerates print modes //! Enumerates print modes
enum PrintMode { pmSummary, pmInterpreted, pmValues, pmHexdump, pmIptc, enum PrintMode { pmSummary, pmInterpreted, pmValues, pmHexdump, pmIptc,

@ -66,8 +66,28 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions // class member definitions
namespace Exiv2 { namespace Exiv2 {
int ImageFactory::Init::count = 0;
ImageFactory::Init::Init()
{
++count;
}
ImageFactory::Init::~Init()
{
if (--count == 0) {
Exiv2::ImageFactory::cleanup();
}
}
ImageFactory::Registry* ImageFactory::registry_ = 0; ImageFactory::Registry* ImageFactory::registry_ = 0;
void ImageFactory::cleanup()
{
delete registry_;
registry_ = 0;
}
void ImageFactory::init() void ImageFactory::init()
{ {
if (0 == registry_) { if (0 == registry_) {

@ -252,6 +252,8 @@ namespace Exiv2 {
public: public:
//! @name Manipulators //! @name Manipulators
//@{ //@{
//! Destructor.
static void cleanup();
/*! /*!
@brief Register image type together with its function pointers. @brief Register image type together with its function pointers.
@ -372,6 +374,24 @@ namespace Exiv2 {
static Image::Type getType(BasicIo& io); static Image::Type getType(BasicIo& io);
//@} //@}
/*!
@brief Class Init is used to execute initialisation and termination
code exactly once, at the begin and end of the program.
See Bjarne Stroustrup, 'The C++ Programming Language 3rd
Edition', section 21.5.2 for details about this pattern.
*/
class Init {
static int count; //!< Counts calls to constructor
public:
//! @name Creators
//@{
//! Perform one-time initialisations.
Init();
//! Perform one-time cleanup operations.
~Init();
//@}
};
private: private:
//! @name Creators //! @name Creators
@ -458,4 +478,16 @@ namespace Exiv2 {
} // namespace Exiv2 } // namespace Exiv2
namespace {
/*!
Each translation unit that includes image.hpp declares its own
Init object. The destructor ensures that the factory is properly
freed exactly once.
See Bjarne Stroustrup, 'The C++ Programming Language 3rd
Edition', section 21.5.2 for details about this pattern.
*/
Exiv2::ImageFactory::Init imageFactoryInit;
}
#endif // #ifndef IMAGE_HPP_ #endif // #ifndef IMAGE_HPP_

@ -184,9 +184,42 @@ namespace Exiv2 {
return AutoPtr(clone_()); return AutoPtr(clone_());
} }
int MakerNoteFactory::Init::count = 0;
MakerNoteFactory::Init::Init()
{
++count;
}
MakerNoteFactory::Init::~Init()
{
if (--count == 0) {
Exiv2::MakerNoteFactory::cleanup();
}
}
MakerNoteFactory::Registry* MakerNoteFactory::pRegistry_ = 0; MakerNoteFactory::Registry* MakerNoteFactory::pRegistry_ = 0;
MakerNoteFactory::IfdIdRegistry* MakerNoteFactory::pIfdIdRegistry_ = 0; MakerNoteFactory::IfdIdRegistry* MakerNoteFactory::pIfdIdRegistry_ = 0;
void MakerNoteFactory::cleanup()
{
if (pRegistry_ != 0) {
Registry::iterator e = pRegistry_->end();
for (Registry::iterator i = pRegistry_->begin(); i != e; ++i) {
delete i->second;
}
delete pRegistry_;
}
if (pIfdIdRegistry_ != 0) {
IfdIdRegistry::iterator e = pIfdIdRegistry_->end();
for (IfdIdRegistry::iterator i = pIfdIdRegistry_->begin(); i != e; ++i) {
delete i->second;
}
delete pIfdIdRegistry_;
}
}
void MakerNoteFactory::init() void MakerNoteFactory::init()
{ {
if (0 == pRegistry_) { if (0 == pRegistry_) {
@ -203,6 +236,11 @@ namespace Exiv2 {
init(); init();
MakerNote* pMakerNote = makerNote.release(); MakerNote* pMakerNote = makerNote.release();
assert(pMakerNote); assert(pMakerNote);
IfdIdRegistry::iterator pos = pIfdIdRegistry_->find(ifdId);
if (pos != pIfdIdRegistry_->end()) {
delete pos->second;
pos->second = 0;
}
(*pIfdIdRegistry_)[ifdId] = pMakerNote; (*pIfdIdRegistry_)[ifdId] = pMakerNote;
} // MakerNoteFactory::registerMakerNote } // MakerNoteFactory::registerMakerNote

@ -344,6 +344,8 @@ namespace Exiv2 {
*/ */
class MakerNoteFactory { class MakerNoteFactory {
public: public:
//! Destructor.
static void cleanup();
/*! /*!
@brief Register a %MakerNote create function for a camera make and @brief Register a %MakerNote create function for a camera make and
model. model.
@ -442,6 +444,25 @@ namespace Exiv2 {
*/ */
static int match(const std::string& regEntry, const std::string& key); static int match(const std::string& regEntry, const std::string& key);
/*!
@brief Class Init is used to execute initialisation and termination
code exactly once, at the begin and end of the program.
See Bjarne Stroustrup, 'The C++ Programming Language 3rd
Edition', section 21.5.2 for details about this pattern.
*/
class Init {
static int count; //!< Counts calls to constructor
public:
//! @name Creators
//@{
//! Perform one-time initialisations.
Init();
//! Perform one-time cleanup operations.
~Init();
//@}
};
private: private:
//! @name Creators //! @name Creators
//@{ //@{
@ -471,4 +492,16 @@ namespace Exiv2 {
} // namespace Exiv2 } // namespace Exiv2
namespace {
/*!
Each translation unit that includes makernote.hpp declares its own
Init object. The destructor ensures that the factory is properly
freed exactly once.
See Bjarne Stroustrup, 'The C++ Programming Language 3rd
Edition', section 21.5.2 for details about this pattern.
*/
Exiv2::MakerNoteFactory::Init makerNoteFactoryInit;
}
#endif // #ifndef MAKERNOTE_HPP_ #endif // #ifndef MAKERNOTE_HPP_

Loading…
Cancel
Save