I have a vector of strings which are changing its contents for no apparent reason. Can't really explain what is going on. Sorry for a long listing, but it's really bugging me.
I have a GUI application which loads some files and uses a reader object which state can be set by using a parse(int argc, char* argv[]) method. The arguments are set in a dialog by checking various boxes and entering values. Here is a struct I use to hold the data from the dialog:
struct PointFilter { PointFilter(): argc(0) {}; ~PointFilter() {}; int argc; std::vector<std::string> args; }; This struct is a member of the dialog class and after pressing ok button its populated with appropriate values. The values are taken from text boxes on the dialog into a stringstream and then pushed back into a std::vector:
class AdvancedLoadDialog { public: AdvancedLoadDialog(const Glib::RefPtr<Gtk::Builder>&); ~AdvancedLoadDialog(); PointFilter get_point_filter() { return this->point_filter; } private: PointFilter point_filter; void on_ok_btn_clicked(); void AdvancedLoadDialog::on_ok_btn_clicked() { std::stringstream filter_stream; // filter_stream << some_values_from_textboxes ... std::vector<std::string> args; std::string arg; // we need a dummy first argument to emulate the command line args.push_back("filter"); while (filter_stream >> arg) { args.push_back(arg); } point_filter.argc = args.size() > 1 ? args.size() : 0; point_filter.args = args; advanced_load_dialog->hide_all(); } Everything works fine till this point and we have an AdvancedLoadDialog object with point_filter member which holds our arguments. Now in a separate window I take the point_filter object and pass it to a constructor of LoadWorker class, which loads the files and also has a PointFilter member.
load_worker = new LoadWorker(..., advanced_load_dialog->get_point_filter()) And then:
LoadWorker::LoadWorker(..., PointFilter pf) : point_filter (pf) All well and good. Now in the LoadWorker::run() function I take the arguments from the point_filter, convert them into std::vector and pass them them to the `parse(int argc, char* argv[]) function I need.
void LoadWorker::run() { std::cout << "LoadWorker::file_filter contents: \n" << "point_filter.argc: " << point_filter.argc << "\n" << "point_filter.args: " << std::endl; for (int i = 0; i < point_filter.argc; ++i) std::cout << point_filter.args[i] << std::endl; // ... if (point_filter.argc != 0) { std::cout << "Using filter: " << std::endl; std::vector<char*> argv; for (std::vector<std::string>::const_iterator it = point_filter.args.begin(); it != point_filter.args.end(); ++it) { argv.push_back(const_cast<char*>(it->c_str())); } argv.push_back(0); for (int i = 0; i < point_filter.argc; ++i) { std::cout << argv[i] << std::endl; } if (!lasreadopener.parse(point_filter.argc, &argv[0])) { send_message("Error parsing filter parameters."); sig_fail(); return; } } } Now this works... once. You can notice that the arguments are printed twice, first as elements of LoadWorker::point_filter.args vector and then as elements of the vector<char*> argv. If I set the filter and then press the load button it all works. If I then try to load another file, without changing AdvancedLoadDialog::point_filter at all, the arguments are disappearing. Here's an example output trying to load two files in a row.
LoadWorker::file_filter contents: point_filter.argc: 6 point_filter.args: filter -clip_z_above 12 -keep_intensity 11 222 Using filter: filter -clip_z_above 12 -keep_intensity 11 222 LoadWorker::file_filter contents: point_filter.argc: 6 point_filter.args: filter clip_z_above 2 keep_intensity 1 22 Using filter: filter
// 6 blank lines here
To make it even more odd, during the second run each string except the first one in point_filter.args is missing the first character and in the argv they are all empty.
Any clues whatsoever?
parsemodify thechar*passed?LoadWorkerobject is deleted and created again every time a load button is pressed. So the contents of point_filter are created again from theAdvancedLoadDialog::point_filterwhich shouldn't change at all.parsefunction modifying the array. Should've checked that first. Thanks.