有如下闭包(不必要的部分和公式部分已简化):
fn solver(u: i32) {
let func_k = move |disp: f64| {
let g1 = (u / 100) as f64;
let gu = disp / 0.01;
let g12 = g1 * g1;
let gu2 = gu * gu;
(g12 * (g12 + gu2).powf(-1.5) - 1.0)
};
let mut model = model::new().set_k_func(func_k);
}
impl model {
pub fn set_k_func(&mut self, Box<dyn Fn(f64) -> f64>) -> &mut self {
// --snip-- //
}
}
直接跳出错误:error:xxxxxxxx(exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
而把变量g1的表达式改为let g1 = u as f64 / 100.0
则可以正常算出结果。我就有点纳闷了,变量u不是被我move进闭包了,这两个式子看起来效果应该是一样的啊?为什么会有这种奇怪的错误?
是我想错了,由于错误的使用了整数除法,导致g1=0,然后在gu=0时,(g12 + gu2).powf(-1.5) = NaN
出现了数据NaN,导致了后来的错误。
1
共 5 条评论, 1 页
评论区
写评论我从C++那里编译了一个Eigen的求解稀疏矩阵的函数作为动态库来给rust用,NaN由于某种我不知道的原因在这个动态库里access violation了。个人猜测大概是eigen特性或者是FFI时候的冲突,总之,我这个动态库貌似只要传入的数据里带有NaN,就会触发access violation。
--
👇
Aya0wind: 你在safe rust里,没有使用外部库的地方出现access violation? 如果真是你摆出的这段代码的问题,那你可以去提交bug了,否则建议查一查你没放出来的那部分代码,特别是带unsafe的。 还有先转浮点再除以100和先除以100再转浮点那可完全不一样,你的u是个整数,除以100的结果还是整数,小数部分就没了。所以我觉得问题并不在闭包这。
你是对的,我仔细排查了下。是我想错了,是你说这个问题。实际想要的是
1.0/100.0 = 0.01
,出错的代码是(1 / 100) as f64 = 0
,然后后来再powf(-1.5)之类的出来的是NaN
,导致了后来的错误。感谢。--
👇
Aya0wind: 你在safe rust里,没有使用外部库的地方出现access violation? 如果真是你摆出的这段代码的问题,那你可以去提交bug了,否则建议查一查你没放出来的那部分代码,特别是带unsafe的。 还有先转浮点再除以100和先除以100再转浮点那可完全不一样,你的u是个整数,除以100的结果还是整数,小数部分就没了。所以我觉得问题并不在闭包这。
试了一下没有问题
测试了一下,除了闭包没有用Box包裹报错以外,并没有大问题。加上Box后运行正常。并未出现你发出的错误。
你在safe rust里,没有使用外部库的地方出现access violation? 如果真是你摆出的这段代码的问题,那你可以去提交bug了,否则建议查一查你没放出来的那部分代码,特别是带unsafe的。 还有先转浮点再除以100和先除以100再转浮点那可完全不一样,你的u是个整数,除以100的结果还是整数,小数部分就没了。所以我觉得问题并不在闭包这。