
I'm starting to use boost::program_options and am not having much luck:
-home-> ./options_test Got debug value default Got option default Segmentation fault (core dumped)
-home-> ./options_test --help free(): invalid pointer 0x8fb06f8! free(): invalid pointer 0x8fafcd0! Got debug value default Got option default Segmentation fault (core dumped)
-home-> ./options_test --help --debug io free(): invalid pointer 0x8a83ec0! free(): invalid pointer 0x8a83ed0! free(): invalid pointer 0x8a83ec8! free(): invalid pointer 0x8a84a38! Segmentation fault (core dumped)
At first I thought it might be a problem with the -mt version as my larger application is threaded. But I compiled the testcase attached below as a single-threaded application and it still fails in the same ways. I'm not sure if my use of vector<string> is correct. The documentation is confusing on this point. In http://boost.sourceforge.net/doc/html/program_options/overview.html one example with the "email" option uses multitoken with "string" and another uses "combining" with "vector<string>." Is it not possible to have a combining and multitoken option value? What's the correct value type to use if I want the multiple tokens for the "debug" option to appear as separate items in a vector (or other sequence)? Or do I have to stuff them in a single string and manually parse them out later? -Dave ------------------------ #include <boost/bind.hpp> #include <boost/program_options.hpp> //#include <boost/filesystem/operations.hpp> //#include <boost/filesystem/fstream.hpp> #include <vector> #include <string> #include <iostream> #include <algorithm> #include <iterator> std::ostream &operator<<(std::ostream &out, const std::vector<std::string> &value); std::ostream &operator<<(std::ostream &out, const std::vector<std::string> &value) { std::copy(value.begin(), value.end(), std::ostream_iterator<std::string>(out, " ")); return(out); } namespace test { namespace opt = boost::program_options; //namespace fs = boost::filesystem; static void validate_debug_options(const opt::options_description &debug, const std::vector<std::string> &value) { std::cout << "Got debug value " << value << std::endl; for(std::vector<std::string>::const_iterator i = value.begin(); i != value.end(); ++i) { std::cout << "Got option " << *i << std::endl; } } void process_options(int argc, char **argv) { opt::options_description help("Help options"); opt::options_description debug("Debug options"); opt::options_description cmdline_options; opt::options_description cfgfile_options; help.add_options() ("help", "This help message"); typedef std::vector<std::string> option_vector; option_vector default_debug_flags; default_debug_flags.push_back("default"); debug.add_options() ("debug,d", opt::value<std::vector<std::string> >()-> // For some reason can't find operator<< declared above default_value(default_debug_flags, "default")-> composing()-> multitoken()-> notifier(boost::bind(validate_debug_options, boost::ref(debug), _1)), "Debug flags:\n\n" " foo: \tDo something\n" " bar: \tDo something else\n" " baz: \tDon't do anything\n"); cmdline_options.add(help).add(debug); cfgfile_options.add(debug); opt::variables_map vm; opt::store(opt::parse_command_line(argc, argv, cmdline_options), vm); // fs::ifstream config_file("./opt.cfg"); // if (config_file) { // opt::store(opt::parse_config_file(config_file, cfgfile_options), vm); // } opt::notify(vm); } } int main(int argc, char **argv) { test::process_options(argc, argv); return(0); }