Random segmentation fault with Vec<Option<NonNull<Node<T>>>>,

The structs:

#[derive(Debug)]
pub struct Node<T> {
    data: Option<T>,
    forward: Vec<Option<NonNull<Node<T>>>>,
}

impl<T> Node<T> {
    fn new(data: T, level: usize) -> Self {
        Node {
            data: Some(data),
            forward: iter::repeat(None).take(level).collect(),
        }
    }
}
pub struct List<T> {
    head: Box<Node<T>>,
}

Part of insertion implementation:

let mut const_ptr: *const Node<T> = self.head.as_ref();
let mut height = self.get_max_height() - 1;
let next_ptr: *mut Node<T> = match (*const_ptr).forward[height] {
    None => { null_mut() }
    Some(mut v) => {
        println!("--- {:?} {:?}",v,(*v.as_ptr()).forward);
        v.as_ptr()
    }
};

I'm trying to use Option<NonNull<Node>> to implement a list structure, the above code is part of my implementation, my code throws segmentation fault exceptions, so I print the forward pointer vector, and I found that its output wasn't always None as I wanted, more often it's an undefined address e.g.:

--- 0x7ffeef8ef030 [Some(0x5000000000000000), Some(0x5000000000000000)]

But occasionally it's None, and my code will work well:

--- 0x7ffee527d030 [None, None]

The inserted data is all the same, but my code produces different results.

So could someone point out where I'm using it wrong?

Any help would be greatly appreciated.

You're using unsafe, so the whole module matters. It will be very difficult to provide assistance without a playground example demonstrating the problem

4 Likes

I'm trying to provide a simple example.

And if I adjust the Node struct to this, replace the vector to slice, it works well

#[derive(Debug)]
pub struct Node<T> {
    data: Option<T>,
    forward: [Option<NonNull<Node<T>>>;K_MAX_HEIGHT]
}

Don't use unsafe :slight_smile:

3 Likes

I did try, but I need these features like NonNull.

No you don't. NonNull in std::ptr - Rust Well yes, you need to dereference it, sorry!

Just don't use NonNull then, use a Box instead

Is NonNull a bit more optimized?

Why would you think so? It shouldn't

What do you recommend to replae Vec<Option<NonNull<Node<T>>>>?

Vec<Option<Box<Node<T>>>>

Got it, I'm going to try it, thanks.

1 Like