Question about mem::forget, ptr::read


#1

From what I understand the code below allocates/frees memory for tmp, len times.

for i in 0..len {
    unsafe {
        // ...
        let tmp = ptr::read(ptr);
        // do something with tmp.
        mem::forget(tmp);
        // ...
    }
}

If so isn’t the code below a better approach? Is there a better way to do this?

let mut tmp: T;

for i in 0..len {
    unsafe {
        // ...
        tmp = ptr::read(ptr);
        // do something with tmp.
        // ...
    }
}

In the docs about mem::forget it says:

Leaks a value into the void, consuming ownership and never running its destructor.

what happens when we directly ptr::read to tmp if tmp had already a value?

Thanks in advance!


#2

ptr::read does not allocate (in the sense of heap allocation). tmp lives on the stack, the whole thing is just a memcpy from the memory pointed to by ptr to the stack region of tmp.


#3

With the unforgotten tmp, if its type has a Drop then that will run before the value is overwritten. That has nothing to do with ptr::read, just normal assignment semantics.

If you want to avoid that, you can use ptr::copy or ptr::copy_nonoverlapping.


#4

@cuviper @troplin Thanks, it makes sense now. Both the ptr::read operation and that mem::forget has to be called before any new ptr::read.