I need a binary tree data structure in C, and there is already exist a binary tree implementation in Rust. So I decided to wrap that.
I made a C-compatible struct contains raw pointer to BTreeMap and add some methods that take a pointer to my wrapper struct.
The problem is in module test. The test is passed if I using my methods only, but whenever I put the println! macro between method calls, The test failed.
use std::collections::BTreeMap;
#[repr(C)]
pub struct my_btree {
btree: *mut BTreeMap<u64, u64>,
}
#[no_mangle]
pub extern "C" fn my_btree_new() -> *mut my_btree {
let boxed = Box::new(BTreeMap::<u64, u64>::new());
let mut ret = my_btree {
btree: Box::into_raw(boxed),
};
&mut ret as *mut my_btree
}
#[no_mangle]
pub extern "C" fn my_btree_insert(
btree: *mut my_btree,
key: u64,
val: u64,
) -> bool {
unsafe {
let mut boxed = Box::from_raw((*btree).btree);
let contains = (*boxed).contains_key(&key);
if contains {
return false;
}
(*boxed).insert(key, val);
println!("{:?}", boxed);
Box::into_raw(boxed);
return true;
}
}
#[no_mangle]
pub extern "C" fn my_btree_contains(btree: *mut my_btree, key: u64) -> bool {
unsafe {
let boxed = Box::from_raw((*btree).btree);
println!("{:?}", boxed);
let ret = (*boxed).contains_key(&key);
Box::into_raw(boxed);
ret
}
}
#[no_mangle]
pub extern "C" fn my_btree_free(btree: *mut my_btree) {
unsafe {
let _boxed = Box::from_raw((*btree).btree);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn insert() {
let map = my_btree_new();
my_btree_insert(map, 1, 1);
my_btree_insert(map, 2, 2);
my_btree_insert(map, 3, 30);
let err = my_btree_contains(map, 1);
assert_eq!(err, true);
println!("???"); // If this line commented out, then test success without error.
my_btree_free(map);
}
}
when I run the test with below command,
$ cargo test -- --nocapture
In my terminal,
running 1 test
{1: 1}
{1: 1, 2: 2}
{1: 1, 2: 2, 3: 30}
{1: 1, 2: 2, 3: 30}
???
error: test failed, to rerun pass '--lib'
But if I comment out the println!("???");
then test pass without any error.
And if I put println between my_btree_insert calls, it failed in next call. It's weird. Why this happened?