Memory leak in unsafe codes

Hey guys,
I'm working on a B+ tree implementation, and I've hit a snag. When I create a Node, I'm encountering a memory leak issue. I'm still learning unsafe and miri, so I'm unsure what's causing this problem. Oddly, I don't encounter any issues when creating a Leaf, but the problem arises when I attempt to wrap Leaf with Node::LEAF. Any insights on what might be causing this memory leak or work around of this issue would be greatly appreciated!

#![feature(allocator_api)]

use std::alloc::Allocator;
use std::ptr::NonNull;

enum Node {
    LEAF(NonNull<Leaf>),
}
impl Node {
    fn init_leaf<A: Allocator + Clone>(alloc: A) -> Self {
        Node::LEAF(unsafe { NonNull::new_unchecked(Box::leak(Box::new_in(Leaf::init(), alloc))) })
    }

    pub fn new_leaf<A: Allocator + Clone>(alloc: A) -> Box<Self, A> {
        Box::new_in(Self::init_leaf(alloc.clone()), alloc)
    }
}

struct Leaf {
    size: usize,
}
impl Leaf {
    fn init() -> Self {
        Self { size: 0 }
    }

    pub fn new<A: Allocator + Clone>(alloc: A) -> Box<Self, A> {
        Box::new_in(Self::init(), alloc.clone())
    }
}




use std::alloc::Global;

fn main() {
    // NO memory leak
    let leaf = Leaf::new(Global);
    
    // Memory leak
    let leaf = Node::LEAF(unsafe { NonNull::new_unchecked(Box::leak(Leaf::new(Global))) });
}

(Playground)

Calling Box::leak will leak memory, that is its purpose.

3 Likes

Look into into_raw_with_allocator and, when destructing, from_raw_in. Or their non-allocator-generic versions (into_raw, from_raw).

2 Likes

Got it, I see what's happening now. Thanks a lot for the assistance, everyone! @quinedot @jumpnbrownweasel

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.