Fix memory leaks in Option

Originally committed to SVN as r4349.
This commit is contained in:
Thomas Goyne 2010-05-23 06:58:11 +00:00
parent 60a1bdc2df
commit 0dc6a082ca
3 changed files with 23 additions and 12 deletions

View file

@ -37,6 +37,9 @@ Options::Options(const std::string &file, const std::string& default_config):
Options::~Options() { Options::~Options() {
Flush(); Flush();
for (OptionValueMap::iterator i = values.begin(); i != values.end(); i++) {
delete i->second;
}
} }
void Options::ConfigNext(std::istream& stream) { void Options::ConfigNext(std::istream& stream) {
@ -60,9 +63,9 @@ void Options::LoadConfig(std::istream& stream) {
json::Reader::Read(config_root, stream); json::Reader::Read(config_root, stream);
} catch (json::Reader::ParseException& e) { } catch (json::Reader::ParseException& e) {
std::cout << "json::ParseException: " << e.what() << ", Line/offset: " << e.m_locTokenBegin.m_nLine + 1 << '/' << e.m_locTokenBegin.m_nLineOffset + 1 << std::endl << std::endl; std::cout << "json::ParseException: " << e.what() << ", Line/offset: " << e.m_locTokenBegin.m_nLine + 1 << '/' << e.m_locTokenBegin.m_nLineOffset + 1 << std::endl << std::endl;
} catch (json::Exception& e) { } catch (json::Exception& e) {
/// @todo Do something better here, maybe print the exact error /// @todo Do something better here, maybe print the exact error
std::cout << "json::Exception: " << e.what() << std::endl; std::cout << "json::Exception: " << e.what() << std::endl;
} }
ConfigVisitor config_visitor(values, std::string("")); ConfigVisitor config_visitor(values, std::string(""));
@ -76,7 +79,7 @@ OptionValue* Options::Get(const std::string &name) {
OptionValueMap::iterator index; OptionValueMap::iterator index;
if ((index = values.find(name)) != values.end()) if ((index = values.find(name)) != values.end())
return index->second; return index->second;
std::cout << "agi::Options::Get Option not found: (" << name << ")" << std::endl; std::cout << "agi::Options::Get Option not found: (" << name << ")" << std::endl;

View file

@ -22,6 +22,8 @@
#ifndef LAGI_PRE #ifndef LAGI_PRE
#include <math.h> #include <math.h>
#include <memory>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/wxcrtvararg.h> #include <wx/wxcrtvararg.h>
#endif #endif
@ -32,7 +34,7 @@
namespace agi { namespace agi {
ConfigVisitor::ConfigVisitor(OptionValueMap &val, const std::string &member_name): values(val) { ConfigVisitor::ConfigVisitor(OptionValueMap &val, const std::string &member_name): values(val) {
// Corropsonding code is in AddOptionValue() // Corresponding code is in AddOptionValue()
name = member_name + "/"; name = member_name + "/";
} }
@ -57,9 +59,9 @@ void ConfigVisitor::Visit(const json::Object& object) {
void ConfigVisitor::Visit(const json::Array& array) { void ConfigVisitor::Visit(const json::Array& array) {
int init = 0; bool init = false;
OptionValueList *array_list; OptionValueList *array_list = NULL;
json::Array::const_iterator index(array.Begin()), indexEnd(array.End()); json::Array::const_iterator index(array.Begin()), indexEnd(array.End());
@ -90,7 +92,7 @@ void ConfigVisitor::Visit(const json::Array& array) {
} else { } else {
throw OptionJsonValueArray("Array type not handled"); throw OptionJsonValueArray("Array type not handled");
} }
init = 1; init = true;
} }
try { try {
@ -115,16 +117,17 @@ void ConfigVisitor::Visit(const json::Array& array) {
Colour col(val); Colour col(val);
array_list->InsertColour(col); array_list->InsertColour(col);
} }
AddOptionValue(array_list);
} catch (agi::Exception&) { } catch (agi::Exception&) {
delete array_list;
throw OptionJsonValueArray("Attempt to insert value into array of wrong type"); throw OptionJsonValueArray("Attempt to insert value into array of wrong type");
} }
} // for index_object } // for index_object
} // for index } // for index
if (array_list) AddOptionValue(array_list);
} }
@ -165,7 +168,7 @@ void ConfigVisitor::Visit(const json::Null& null) {
void ConfigVisitor::AddOptionValue(OptionValue* opt) { void ConfigVisitor::AddOptionValue(OptionValue* opt) {
// Corrosponding code is in the constuctor. // Corresponding code is in the constuctor.
std::string stripped = name.substr(1, name.rfind("/")-1); std::string stripped = name.substr(1, name.rfind("/")-1);
OptionValue *opt_cur; OptionValue *opt_cur;
@ -178,6 +181,10 @@ void ConfigVisitor::AddOptionValue(OptionValue* opt) {
return; return;
} }
// Ensure than opt is deleted at the end of this function even if the Set
// method throws
std::auto_ptr<OptionValue> auto_opt(opt);
int type = opt_cur->GetType(); int type = opt_cur->GetType();
switch (type) { switch (type) {
case OptionValue::Type_String: case OptionValue::Type_String:

View file

@ -20,6 +20,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <memory>
#include <sstream> #include <sstream>
#include <string> #include <string>