问题
I am facing an issue where I have a configuration file and I parse it with boost::property_tree:info_parser.
I use this code to do the work:
struct _Config
{
std::string info[2];
boost::property_tree::ptree pt;
_Config()
{
//check if config file exists, if not create it, etc, do other stuff not related to the issue
//this code reproduces the issue
//DEFAULT VALUE, can be changed by configuration later
info[0] = "If updating this file make sure to update all settings accordingly.";
info[1] = "This program has been created by Name 'Nickname' Lastname";
}
void Save()
{
boost::property_tree::info_parser::write_info(".\\config.cfg", pt);
}
void Load()
{
boost::property_tree::info_parser::read_info(".\\config.cfg", pt);
{
//check if variable already exists in config file, if yes load it to
{
//try to load entry
boost::optional<std::string> v = pt.get_optional<std::string>("Info.a");
if (v.is_initialized())
//overwrite default value
info[0] = v.get();
}
//if entry does not exist it will be created now, else the loaded value will be saved
pt.put<std::string>("Info.a", info[0]);
}
//again for next variable
{
{
boost::optional<std::string> v = pt.get_optional<std::string>("Info.b");
if (v.is_initialized())
info[1] = v.get();
}
pt.put<std::string>("Info.b", info[1]);
}
Save();
}
~_Config()
{
Save();
pt.clear();
}
} Config;
Now,my section does look the first time like this:
Info
{
a "If updating this file make sure to update all settings accordingly."
b "This program has been created by Name 'Nickname' Lastname"
}
when starting again my configuration becomes this when saving:
Info
{
a If updating this file make sure to update all settings accordingly.
b This program has been created by Name 'Nickname' Lastname
}
but after relaunching the code again, the info section becomes a mess and my program breaks:
Info
{
a If
updating this
file make
sure to
update all
accordingly. ""
b This
program has
been created
by Name
'Nickname' Lastname
}
How do I make sure that spaces are an accepted character and the quotes are not removed? I also noticed that any comments I make in the config file are not being saved, is there an option to save them?
I am using boost 1.55 with Visual Studio 2013 on Windows 8 x64 in a 32bit application.
回答1:
It was Undefined Behaviour, specifically
The static initialization fiasco
The manifestation here is quite subtle!
Valgrind told me that info_parser::is_simple_data<char>
is accessing a string freed. That string would be the local static. Both are being called from __run_exit_handlers()
but not in any particular order! See the linked C++FAQ entry for explanations.
Solution, don't depend on global statics with RAII:
int main()
{
_Config Config;
Config.Load();
}
is just fine, see it Live On Coliru
来源:https://stackoverflow.com/questions/23681439/boostproperty-treeinfo-parser-breaks-on-spaces-in-value