to_expr
函数会导致错误。你能告诉我下面的问题吗?
context z3_cont;
expr x = z3_cont.int_const("x");
expr y = z3_cont.int_const("y");
expr ge = ((y==3) && (x==2));
ge = swap_tree( ge );
其中swap_tree
是一个函数,它将交换二进制操作的所有操作数。它定义如下。
expr swap_tree( expr e ) {
Z3_ast ee[2];
if ( e.is_app() && e.num_args() == 2) {
for ( int i = 0; i < 2; ++i ) {
ee[ 1 - i ] = swap_tree( e.arg(i) );
}
for ( int i = 0; i < 2; ++i ) {
cout <<" ee[" << i << "] : " << to_expr( z3_cont, ee[ i ] ) << endl;
}
return to_expr( z3_cont, Z3_update_term( z3_cont, e, 2, ee ) );
}
else
return e;
}
答案 0 :(得分:0)
问题是&#34;引用计数&#34;。如果Z3对象的引用计数器为0,则系统可以对其进行垃圾回收.Z3 C ++ API提供了&#34;智能指针&#34; (expr
,sort
,...)用于自动管理我们的参考计数器。您的代码使用Z3_ast ee[2]
。在for循环中,您将swap_tree(e.arg(0))
的结果存储到ee[0]
中。由于引用计数器没有递增,因此在执行循环的第二次迭代时可能会删除此Z3对象。
这是一个可能的解决方法:
expr swap_tree( expr e ) {
if ( e.is_app() && e.num_args() == 2) {
// using smart-pointers to store the intermediate results.
expr ee0(z3_cont), ee1(z3_cont);
ee0 = swap_tree( e.arg(0) );
ee1 = swap_tree( e.arg(1) );
Z3_ast ee[2] = { ee1, ee0 };
return to_expr( z3_cont, Z3_update_term( z3_cont, e, 2, ee ) );
}
else {
return e;
}
}