标准::矢量<标准::字符串的消失内容>
Disappearing contents of std::vector<std::string>
我有一个字符串向量,它们无缘无故地更改其内容。无法真正解释发生了什么。很抱歉列表很长,但它确实困扰着我。
我有一个 GUI 应用程序,它加载一些文件并使用一个读取器对象,可以使用 parse(int argc, char* argv[])
方法设置其状态。通过选中各种框并输入值,在对话框中设置参数。这是我用来保存对话框中数据的结构:
struct PointFilter
{
PointFilter(): argc(0) {};
~PointFilter() {};
int argc;
std::vector<std::string> args;
};
此结构是对话框类的成员,按 ok 按钮后填充了适当的值。这些值从对话框上的文本框中获取到字符串流中,然后推送回 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();
}
到目前为止一切正常,我们有一个AdvancedLoadDialog
对象point_filter
其中包含保存我们参数的成员。现在在一个单独的窗口中,我获取point_filter对象并将其传递给LoadWorker
类的构造函数,该构造函数加载文件并且还具有PointFilter
成员。
load_worker = new LoadWorker(..., advanced_load_dialog->get_point_filter())
然后:
LoadWorker::LoadWorker(..., PointFilter pf) :
point_filter (pf)
一切都很好。现在在LoadWorker::run()
函数中,我从point_filter中获取参数,将它们转换为 std::vector,并将它们传递给我需要的 'parse(int argc, char* argv[]) 函数。
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;
}
}
}
现在这行得通了...一次。您可以注意到参数被打印了两次,首先作为向量的元素LoadWorker::point_filter.args
然后作为vector<char*> argv
的元素。如果我设置过滤器,然后按加载按钮,一切正常。如果我然后尝试加载另一个文件,而不更改AdvancedLoadDialog::point_filter
,则参数将消失。下面是尝试连续加载两个文件的示例输出。
负载工人::file_filter内容:point_filter.argc:6 point_filter.args:过滤器 -clip_z_above 12 -keep_intensity 11 222 使用过滤器:过滤器 -clip_z_above 12 -keep_intensity 11 222 负载工人::file_filter内容:point_filter.argc:6 point_filter.args:过滤器clip_z_above 2 keep_intensity 1 22 使用过滤器:过滤器
此处为 6 个空白行
更奇怪的是,在第二次运行期间,除了point_filter.args
中的第一个字符串之外,每个字符串都缺少第一个字符,并且在argv
中它们都是空的。
有什么线索吗?
在做涉及std::string::c_str
的事情时要非常非常谨慎,就像你在这里所做的那样:
argv.push_back(const_cast<char*>(it->c_str()));
如果要保留 c_str
提供的值,应先将它们复制到新容器中。
如果要信任 cplusplus.com(并非总是如此),
此数组中的值不应在程序中修改,并且仅保证在下次调用 String 对象的非常量成员函数之前保持不变
虽然我不能立即从其他来源获得更多有用的信息。
在 AdvancedLoadDialog 中,尝试推送已分配的 arg 版本,而不是自动版本。 您似乎正在推送对变量的引用,该变量将在离开 AdvancedDialogLoad 时被销毁。
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- EASTL矢量<向量<int>>连续的
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 如何从Windows应用程序输出到标准?
- 安全到标准:移动会员?
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- 标准::变体的赋值运算符
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 如何在 Mac 上使用 c++17 并行标准库算法?
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?