SIGSEGV in fromStdString
-
I have SIGSEGV inside fromStdString in a line:
ui->lineEdit_2->setText(QString::fromStdString(mainWindow->extensions)); //!!! SIGSEGV
I don't know how to solve the problem. -
I have SIGSEGV inside fromStdString in a line:
ui->lineEdit_2->setText(QString::fromStdString(mainWindow->extensions)); //!!! SIGSEGV
I don't know how to solve the problem.@Robert-M said in SIGSEGV in fromStdString:
mainWindow->extensions
What is this?
IsmainWindow
orextensions
not initialized by any chance? (Probably it's not)Btw: I doesn't crash because of
qstring.h
. There's nothing wrong with it. It crashes, because you are trying to access an invalid object/uninitalized pointer. -
@Robert-M said in SIGSEGV in fromStdString:
mainWindow->extensions
What is this?
IsmainWindow
orextensions
not initialized by any chance? (Probably it's not)Btw: I doesn't crash because of
qstring.h
. There's nothing wrong with it. It crashes, because you are trying to access an invalid object/uninitalized pointer.You're most likley mixing debug and release libraries on windows which is not supported (by MS)
-
@Robert-M said in SIGSEGV in fromStdString:
mainWindow->extensions
What is this?
IsmainWindow
orextensions
not initialized by any chance? (Probably it's not)Btw: I doesn't crash because of
qstring.h
. There's nothing wrong with it. It crashes, because you are trying to access an invalid object/uninitalized pointer.class MainWindow : public QMainWindow { ... std::string extensions; };
I don't understand this:
Q_ASSERT(mainWindow != nullptr); Q_ASSERT(mainWindow->extensions != std::string("")); std::string e = mainWindow->extensions; //!!! here SIGSEGV QString qs = QString::fromStdString(e);
-
You're most likley mixing debug and release libraries on windows which is not supported (by MS)
@Christian-Ehrlicher said in SIGSEGV in fromStdString:
You're most likley mixing debug and release libraries on windows which is not supported (by MS)
What made you think that? Experience?! :)
-
@Christian-Ehrlicher said in SIGSEGV in fromStdString:
You're most likley mixing debug and release libraries on windows which is not supported (by MS)
What made you think that? Experience?! :)
@Pl45m4 said in SIGSEGV in fromStdString:
What made you think that? Experience?! :)
Experience and documentation
-
class MainWindow : public QMainWindow { ... std::string extensions; };
I don't understand this:
Q_ASSERT(mainWindow != nullptr); Q_ASSERT(mainWindow->extensions != std::string("")); std::string e = mainWindow->extensions; //!!! here SIGSEGV QString qs = QString::fromStdString(e);
@Robert-M said:
I don't understand this:
Q_ASSERT(mainWindow != nullptr);
std::string e = mainWindow->extensions; //!!! here SIGSEGVThe
mainWindow
pointer is not nullptr, but it doesn't mean it's valid. Like others mentioned it could be uninitialized garbage or already deleted garbage.Make sure you initialize it to nullptr where you declare it. That would help you check the first problem.
If that's not it then put a breakpoint at that line and compare the value of the pointer to the address of the main window object or put a breakpoint in the main window destructor to see if it's not deleted before you use the pointer.Also would be good to post where and how you initialize that
mainWindow
pointer. -
@Pl45m4 said in SIGSEGV in fromStdString:
What made you think that? Experience?! :)
Experience and documentation
void MainWindow::on_actionSet_other_options_triggered() { action_cancelled = false; if (mode == "B") { if (QMessageBox::information(this, "Information", "You will be asked to set some additional options. Note that obfuscating properties/variables depend on framework code (for example CodeIgniter does not allow for obfuscating variables in views because such variables are passed as view parameters in controller).", QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { action_cancelled = true; return; } } OtherOptionsDialog *options = new OtherOptionsDialog(this, this); // !!! this IS NOT nullptr options->exec(); set_dirtyphp_command(""); set_menu_options(); } OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION { ui->setupUi(this); setFixedSize(size()); ui->checkBox->setChecked(!mainWindow->no_check); ui->checkBox_5->setChecked(mainWindow->allow_reflection); ui->spinBox->setMinimum(::min_random_identifiers_length); ui->spinBox->setMaximum(::default_random_identifiers_length * 3); ui->spinBox->setValue(mainWindow->random_identifiers_length); ui->lineEdit->setValidator(new QIntValidator(ui->lineEdit)); ui->lineEdit->setText(QString::fromStdString(std::to_string(mainWindow->max_line_len))); QRegularExpression rx1("([a-zA-Z0-9_\\-\\+]+,)*[a-zA-Z0-9_\\-\\+]+"); QValidator *validator1 = new QRegularExpressionValidator(rx1, ui->lineEdit_2); ui->lineEdit_2->setValidator(validator1); Q_ASSERT(mainWindow != nullptr); Q_ASSERT(mainWindow->extensions != std::string("")); std::string e = mainWindow->extensions; //!!! SIGSEGV QString qs = QString::fromStdString(e); ui->lineEdit_2->setText(qs); ui->checkBox_2->setChecked(mainWindow->obfpctl); ui->checkBox_3->setChecked(mainWindow->obfpmdl); ui->checkBox_6->setChecked(mainWindow->obfpvw); ui->checkBox_4->setChecked(mainWindow->obfvvw); ui->lineEdit_3->setText(QString::fromStdString(mainWindow->reserved)); QRegularExpression rx2(QString::fromStdString("(" + ::identifier + ",)*(" + ::identifier + ")?")); QValidator *validator2 = new QRegularExpressionValidator(rx2, ui->lineEdit_3); ui->lineEdit_3->setValidator(validator2); }
-
void MainWindow::on_actionSet_other_options_triggered() { action_cancelled = false; if (mode == "B") { if (QMessageBox::information(this, "Information", "You will be asked to set some additional options. Note that obfuscating properties/variables depend on framework code (for example CodeIgniter does not allow for obfuscating variables in views because such variables are passed as view parameters in controller).", QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { action_cancelled = true; return; } } OtherOptionsDialog *options = new OtherOptionsDialog(this, this); // !!! this IS NOT nullptr options->exec(); set_dirtyphp_command(""); set_menu_options(); } OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION { ui->setupUi(this); setFixedSize(size()); ui->checkBox->setChecked(!mainWindow->no_check); ui->checkBox_5->setChecked(mainWindow->allow_reflection); ui->spinBox->setMinimum(::min_random_identifiers_length); ui->spinBox->setMaximum(::default_random_identifiers_length * 3); ui->spinBox->setValue(mainWindow->random_identifiers_length); ui->lineEdit->setValidator(new QIntValidator(ui->lineEdit)); ui->lineEdit->setText(QString::fromStdString(std::to_string(mainWindow->max_line_len))); QRegularExpression rx1("([a-zA-Z0-9_\\-\\+]+,)*[a-zA-Z0-9_\\-\\+]+"); QValidator *validator1 = new QRegularExpressionValidator(rx1, ui->lineEdit_2); ui->lineEdit_2->setValidator(validator1); Q_ASSERT(mainWindow != nullptr); Q_ASSERT(mainWindow->extensions != std::string("")); std::string e = mainWindow->extensions; //!!! SIGSEGV QString qs = QString::fromStdString(e); ui->lineEdit_2->setText(qs); ui->checkBox_2->setChecked(mainWindow->obfpctl); ui->checkBox_3->setChecked(mainWindow->obfpmdl); ui->checkBox_6->setChecked(mainWindow->obfpvw); ui->checkBox_4->setChecked(mainWindow->obfvvw); ui->lineEdit_3->setText(QString::fromStdString(mainWindow->reserved)); QRegularExpression rx2(QString::fromStdString("(" + ::identifier + ",)*(" + ::identifier + ")?")); QValidator *validator2 = new QRegularExpressionValidator(rx2, ui->lineEdit_3); ui->lineEdit_3->setValidator(validator2); }
@Robert-M
void MainWindow::on_actionSet_other_options_triggered() { action_cancelled = false; if (mode == "B") { if (QMessageBox::information(this, "Information", "You will be asked to set some additional options. Note that obfuscating properties/variables depend on framework code (for example CodeIgniter does not allow for obfuscating variables in views because such variables are passed as view parameters in controller).", QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { action_cancelled = true; return; } } OtherOptionsDialog *options = new OtherOptionsDialog(this, this); options->exec(); set_dirtyphp_command(""); set_menu_options(); }
-
void MainWindow::on_actionSet_other_options_triggered() { action_cancelled = false; if (mode == "B") { if (QMessageBox::information(this, "Information", "You will be asked to set some additional options. Note that obfuscating properties/variables depend on framework code (for example CodeIgniter does not allow for obfuscating variables in views because such variables are passed as view parameters in controller).", QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { action_cancelled = true; return; } } OtherOptionsDialog *options = new OtherOptionsDialog(this, this); // !!! this IS NOT nullptr options->exec(); set_dirtyphp_command(""); set_menu_options(); } OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION { ui->setupUi(this); setFixedSize(size()); ui->checkBox->setChecked(!mainWindow->no_check); ui->checkBox_5->setChecked(mainWindow->allow_reflection); ui->spinBox->setMinimum(::min_random_identifiers_length); ui->spinBox->setMaximum(::default_random_identifiers_length * 3); ui->spinBox->setValue(mainWindow->random_identifiers_length); ui->lineEdit->setValidator(new QIntValidator(ui->lineEdit)); ui->lineEdit->setText(QString::fromStdString(std::to_string(mainWindow->max_line_len))); QRegularExpression rx1("([a-zA-Z0-9_\\-\\+]+,)*[a-zA-Z0-9_\\-\\+]+"); QValidator *validator1 = new QRegularExpressionValidator(rx1, ui->lineEdit_2); ui->lineEdit_2->setValidator(validator1); Q_ASSERT(mainWindow != nullptr); Q_ASSERT(mainWindow->extensions != std::string("")); std::string e = mainWindow->extensions; //!!! SIGSEGV QString qs = QString::fromStdString(e); ui->lineEdit_2->setText(qs); ui->checkBox_2->setChecked(mainWindow->obfpctl); ui->checkBox_3->setChecked(mainWindow->obfpmdl); ui->checkBox_6->setChecked(mainWindow->obfpvw); ui->checkBox_4->setChecked(mainWindow->obfvvw); ui->lineEdit_3->setText(QString::fromStdString(mainWindow->reserved)); QRegularExpression rx2(QString::fromStdString("(" + ::identifier + ",)*(" + ::identifier + ")?")); QValidator *validator2 = new QRegularExpressionValidator(rx2, ui->lineEdit_3); ui->lineEdit_3->setValidator(validator2); }
@Robert-M said in SIGSEGV in fromStdString:
The parentWindow parameter is being set to a MainWindow* in the creation of the dialog:
OtherOptionsDialog *options = new OtherOptionsDialog(this, this); // !!! this IS NOT nullptr
but the constructor parameter is an actual MainWindow:
OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION {...
How is the pointer to initialise an actual MainWindow object?
MainWindow is a QObject. You cannot pass a QObject by value, i.e. copy a QObject, as you do in this constructor. Assuming it does something to make this happen, the
mainWindow
member variable of OtherOptionsDialog is, it seems, a MainWindow* which cannot be constructed from an actual MainWindow.Either this is your code and it does not compile, or this is not your code.
-
@Robert-M said in SIGSEGV in fromStdString:
The parentWindow parameter is being set to a MainWindow* in the creation of the dialog:
OtherOptionsDialog *options = new OtherOptionsDialog(this, this); // !!! this IS NOT nullptr
but the constructor parameter is an actual MainWindow:
OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION {...
How is the pointer to initialise an actual MainWindow object?
MainWindow is a QObject. You cannot pass a QObject by value, i.e. copy a QObject, as you do in this constructor. Assuming it does something to make this happen, the
mainWindow
member variable of OtherOptionsDialog is, it seems, a MainWindow* which cannot be constructed from an actual MainWindow.Either this is your code and it does not compile, or this is not your code.
@ChrisW67
I don't know why Qt forum did not display asterisk before parameter parentWindow.OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) {
-
@ChrisW67
I don't know why Qt forum did not display asterisk before parameter parentWindow.OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) {
@Robert-M said in SIGSEGV in fromStdString:
don't know why Qt forum did not display asterisk before parameter parentWindow.
Because you don't format your code properly - use the format tags provided by the forum software!
-
@ChrisW67
I don't know why Qt forum did not display asterisk before parameter parentWindow.OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) {
@Robert-M
As @Christian-Ehrlicher said, please use the forum's Code tags to enclose blocks of code you want others to look at.If you want an answer please reduce your code to some kind of minimal example. Literally the majority of the code you show cannot be relevant to your issue: message boxes, regular expressions, validators, spinboxes, line edits, etc. etc. How are these required or implicated? If you reduce your code to a minimum then maybe either you will spot the problem yourself or someone else will.
-
@ChrisW67
I don't know why Qt forum did not display asterisk before parameter parentWindow.OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) {
-
@Robert-M
I tried to run the code in Linux.
I see:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)@Robert-M
Great. So what are you going to do to simplify to find out why? The code you have posted is on the one hand too large and on the other incomplete.Let's take a "random" example of what could be going on in your code, for all we know:
char array1[4]; std::string extensions; char array2[4]; ... memcpy(array1, "12345678", 8); memcpy(array2, "12345678", 8); ... qDebug() << mainwindow->extensions;
(I put in both above & below because not sure which direction stack/member layout grows.) It's an example. That's why you need to create and paste a minimal example of actual code going wrong....
-
void MainWindow::on_actionSet_other_options_triggered() { action_cancelled = false; if (mode == "B") { if (QMessageBox::information(this, "Information", "You will be asked to set some additional options. Note that obfuscating properties/variables depend on framework code (for example CodeIgniter does not allow for obfuscating variables in views because such variables are passed as view parameters in controller).", QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { action_cancelled = true; return; } } OtherOptionsDialog *options = new OtherOptionsDialog(this, this); // !!! this IS NOT nullptr options->exec(); set_dirtyphp_command(""); set_menu_options(); } OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION { ui->setupUi(this); setFixedSize(size()); ui->checkBox->setChecked(!mainWindow->no_check); ui->checkBox_5->setChecked(mainWindow->allow_reflection); ui->spinBox->setMinimum(::min_random_identifiers_length); ui->spinBox->setMaximum(::default_random_identifiers_length * 3); ui->spinBox->setValue(mainWindow->random_identifiers_length); ui->lineEdit->setValidator(new QIntValidator(ui->lineEdit)); ui->lineEdit->setText(QString::fromStdString(std::to_string(mainWindow->max_line_len))); QRegularExpression rx1("([a-zA-Z0-9_\\-\\+]+,)*[a-zA-Z0-9_\\-\\+]+"); QValidator *validator1 = new QRegularExpressionValidator(rx1, ui->lineEdit_2); ui->lineEdit_2->setValidator(validator1); Q_ASSERT(mainWindow != nullptr); Q_ASSERT(mainWindow->extensions != std::string("")); std::string e = mainWindow->extensions; //!!! SIGSEGV QString qs = QString::fromStdString(e); ui->lineEdit_2->setText(qs); ui->checkBox_2->setChecked(mainWindow->obfpctl); ui->checkBox_3->setChecked(mainWindow->obfpmdl); ui->checkBox_6->setChecked(mainWindow->obfpvw); ui->checkBox_4->setChecked(mainWindow->obfvvw); ui->lineEdit_3->setText(QString::fromStdString(mainWindow->reserved)); QRegularExpression rx2(QString::fromStdString("(" + ::identifier + ",)*(" + ::identifier + ")?")); QValidator *validator2 = new QRegularExpressionValidator(rx2, ui->lineEdit_3); ui->lineEdit_3->setValidator(validator2); }
@Robert-M said in SIGSEGV in fromStdString:
OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow parentWindow) :
QDialog(parent),
ui(new Ui::OtherOptionsDialog),
mainWindow(parentWindow) // !!! HERE INITIALISATION
{
ui->setupUi(this);
setFixedSize(size());
ui->checkBox->setChecked(!mainWindow->no_check);
ui->checkBox_5->setChecked(mainWindow->allow_reflection);
ui->spinBox->setMinimum(::min_random_identifiers_length);
ui->spinBox->setMaximum(::default_random_identifiers_length * 3);
ui->spinBox->setValue(mainWindow->random_identifiers_length);
ui->lineEdit->setValidator(new QIntValidator(ui->lineEdit));
ui->lineEdit->setText(QString::fromStdString(std::to_string(mainWindow->max_line_len)));
QRegularExpression rx1("([a-zA-Z0-9_\-\+]+,)[a-zA-Z0-9_\-\+]+");
QValidator validator1 = new QRegularExpressionValidator(rx1, ui->lineEdit_2);
ui->lineEdit_2->setValidator(validator1);
Q_ASSERT(mainWindow != nullptr);
Q_ASSERT(mainWindow->extensions != std::string(""));
std::string e = mainWindow->extensions; //!!! SIGSEGV
QString qs = QString::fromStdString(e);
ui->lineEdit_2->setText(qs);
ui->checkBox_2->setChecked(mainWindow->obfpctl);
ui->checkBox_3->setChecked(mainWindow->obfpmdl);
ui->checkBox_6->setChecked(mainWindow->obfpvw);
ui->checkBox_4->setChecked(mainWindow->obfvvw);
ui->lineEdit_3->setText(QString::fromStdString(mainWindow->reserved));
QRegularExpression rx2(QString::fromStdString("(" + ::identifier + ",)(" + ::identifier + ")?"));
QValidator *validator2 = new QRegularExpressionValidator(rx2, ui->lineEdit_3);
ui->lineEdit_3->setValidator(validator2);
}Instead of passing
this
twice to yourOtherOptionsDialog
asQWidget
andQMainWindow
to access some data, you should pass the data directly. You seem to read-only anyway.
I assume,obfpctl
,obfpmdl
,obfpvw
andobfvvw
are boolean andextensions
is a string.
So changeOtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION
to something like
OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, QVector<QVariant> &data) : QDialog(parent), ui(new Ui::OtherOptionsDialog)
and pass the data with c'tor
QVector<QVariant> data; data.push_back(obfpctl); data.push_back(obfpmdl); data.push_back(obfpvw); data.push_back(obfvvw); data.push_back(QString::fromStdString(extensions); OtherOptionsDialog *options = new OtherOptionsDialog(this, data);
Since it's a constant data structure, you know the order of your data and can access it with
data.at(...)
ordata[...]
in your dialog class.
It's weird to pass the wholemainWindow
to an options dialog just to read some variables.
Maybe you want to re-think your whole design -
@Robert-M said in SIGSEGV in fromStdString:
OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow parentWindow) :
QDialog(parent),
ui(new Ui::OtherOptionsDialog),
mainWindow(parentWindow) // !!! HERE INITIALISATION
{
ui->setupUi(this);
setFixedSize(size());
ui->checkBox->setChecked(!mainWindow->no_check);
ui->checkBox_5->setChecked(mainWindow->allow_reflection);
ui->spinBox->setMinimum(::min_random_identifiers_length);
ui->spinBox->setMaximum(::default_random_identifiers_length * 3);
ui->spinBox->setValue(mainWindow->random_identifiers_length);
ui->lineEdit->setValidator(new QIntValidator(ui->lineEdit));
ui->lineEdit->setText(QString::fromStdString(std::to_string(mainWindow->max_line_len)));
QRegularExpression rx1("([a-zA-Z0-9_\-\+]+,)[a-zA-Z0-9_\-\+]+");
QValidator validator1 = new QRegularExpressionValidator(rx1, ui->lineEdit_2);
ui->lineEdit_2->setValidator(validator1);
Q_ASSERT(mainWindow != nullptr);
Q_ASSERT(mainWindow->extensions != std::string(""));
std::string e = mainWindow->extensions; //!!! SIGSEGV
QString qs = QString::fromStdString(e);
ui->lineEdit_2->setText(qs);
ui->checkBox_2->setChecked(mainWindow->obfpctl);
ui->checkBox_3->setChecked(mainWindow->obfpmdl);
ui->checkBox_6->setChecked(mainWindow->obfpvw);
ui->checkBox_4->setChecked(mainWindow->obfvvw);
ui->lineEdit_3->setText(QString::fromStdString(mainWindow->reserved));
QRegularExpression rx2(QString::fromStdString("(" + ::identifier + ",)(" + ::identifier + ")?"));
QValidator *validator2 = new QRegularExpressionValidator(rx2, ui->lineEdit_3);
ui->lineEdit_3->setValidator(validator2);
}Instead of passing
this
twice to yourOtherOptionsDialog
asQWidget
andQMainWindow
to access some data, you should pass the data directly. You seem to read-only anyway.
I assume,obfpctl
,obfpmdl
,obfpvw
andobfvvw
are boolean andextensions
is a string.
So changeOtherOptionsDialog::OtherOptionsDialog(QWidget *parent, MainWindow *parentWindow) : QDialog(parent), ui(new Ui::OtherOptionsDialog), mainWindow(parentWindow) // !!! HERE INITIALISATION
to something like
OtherOptionsDialog::OtherOptionsDialog(QWidget *parent, QVector<QVariant> &data) : QDialog(parent), ui(new Ui::OtherOptionsDialog)
and pass the data with c'tor
QVector<QVariant> data; data.push_back(obfpctl); data.push_back(obfpmdl); data.push_back(obfpvw); data.push_back(obfvvw); data.push_back(QString::fromStdString(extensions); OtherOptionsDialog *options = new OtherOptionsDialog(this, data);
Since it's a constant data structure, you know the order of your data and can access it with
data.at(...)
ordata[...]
in your dialog class.
It's weird to pass the wholemainWindow
to an options dialog just to read some variables.
Maybe you want to re-think your whole design -
@Pl45m4
According to your advice I defined struct other_options.
Program works fine, there's no SIGSEGV.
Problem solved.
Thanks. -
@Robert-M
Using struct instead of QVector<QVariant> produced simpler and smaller code.
What is adventage of using QVector<QVariant> instead of struct?This post is deleted!