Memory Layout changes its size after calling function alocat()

https://gist.github.com/rust-play/9ae00ec2ef12ce91bdf091be1d739d18

In this code, you set block_ptr and ptr_ and data to all point to the same address. Then you write your Block to that address, and set its start and ptr fields to point to that same address:

let data = alloc(layout.unwrap());
let data = NonNull::new(data)?;

let block_ptr = (data.as_ptr() as usize) as *mut Block;

let ptr_: Cell<NonNull<u8>> =
    Cell::new(NonNull::new_unchecked(data.as_ptr() as *mut u8));
let prev_chunk = Cell::new(0);

write(
    block_ptr,
    Block {
        layout: layout.unwrap(),
        prevChunkSize: prev_chunk,
        prev_block: Cell::new(prev_block),
        start: data,
        ptr: ptr_,
    },
);

Then in allocat, you write stuff to the address in the ptr field:

write(tmp_chunk.ptr.get().as_ptr() as usize as *mut T, stuff);

But this is the address where the Block itself lives, so this overwrites some or all of the Block, causing the memory corruption that you are seeing.

The variable name block_footer makes me think maybe you intended to place the Block at the end of the allocation, but you have accidentally placed it at the start of the allocation. Currently it is a header rather than a footer.

Thanks for the response.

I found out that the struct Block itself needs 48 bytes . So I set the ptr attribute of that struct to the adress start + 48 bytes and allocate memory from now on from their.
And it works now!
Didnt know that the struct itself needs that much memory.

Note that the alignment also has to be at least that of Block, and when you allocate a T in the chunk it also has to be aligned to align_of<T>().

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.