The piece of code below is to evaluate expression string "x3 - y"
.
The expression should be evaluated as2 cause x3 should be evaluated as 3 and y should be 1. However, it's evaluated as -1
I tried to print the value of x3 and y. It prints 3 and 1 for x3 and y, which is expected.
I also tried to replace add_variable
with method create_variable
, and it output correct result.
so what's wrong with the piece of code?
void test() {
typedef exprtk::symbol_table<double> symbol_table_t;
typedef exprtk::expression<double> expression_t;
typedef exprtk::parser<double> parser_t;
std::string expression_str = "x3 - y";
symbol_table_t symbol_table;
double y = 1;
std::vector<double> xs;
for (int i = 0; i < 5; i++) {
xs.push_back(i);
// symbol_table.create_variable("x"+ std::to_string(i), xs[i]); The output is correct if use create_variable
symbol_table.add_variable("x"+ std::to_string(i), xs[i]);
}
symbol_table.add_variable("y", y);
std::cout << symbol_table.get_variable("x3")->value() << " " << symbol_table.get_variable("y")->value() << std::endl; // x3 == 3, y == 1
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t tmp_parser;
tmp_parser.compile(expression_str, expression);
std::cout << expression.value(); // output is -1
}
The answer provided by @IgorTandetnik is correct. The method
symbol_table.add_variable
takes references to the variables passed to it. By adding more variables to thevector
xs via thepush_back
method, a resize of the vector may occur, which will invalidate the previous references taken from xs that are present in thesymbol_table
instance.From the ExprTk readme.txt Section 10.1 there is the following code listing that denotes the various ways variables that have been added to a
symbol_table
can be invalidated: