rust-lang / nomicon

The Dark Arts of Advanced and Unsafe Rust Programming
https://doc.rust-lang.org/nomicon/
Apache License 2.0
1.75k stars 256 forks source link

what is heap::deallocate? #370

Open gftea opened 2 years ago

gftea commented 2 years ago

A example in https://github.com/rust-lang/nomicon/blob/master/src/leaking.md

// drop the data and then free it
                ptr::read(self.ptr);
                heap::deallocate(self.ptr);
botahamec commented 2 years ago

Notice the comment that says, "Wouldn't it be nice if heap::allocate worked like this?" It's not a real function

gftea commented 2 years ago

If heap::deallocate is to free heap, why need to calling ptr::read which will also drop the memory

botahamec commented 2 years ago

@gftea Not every type implements Drop, and the types that do won't know that they've been allocated on the heap, or where they are in memory, so they can't free themselves. For example, String contains a pointer to some memory that's on the heap. When it's dropped, it'll deallocate the memory that it put on the heap, but it can't deallocate itself, so if you don't deallocate it, the pointer to free memory will remain on the heap, unused.

gftea commented 2 years ago

@botahamec , thanks, but in our example, why ptr::read needed?, it just "Reads the value from src without moving it. This leaves the memory in src unchanged."

                ptr::read(self.ptr);              // this read value of RcBox, leave self.ptr unchanged, what is point here?
                heap::deallocate(self.ptr); // free the heap for RcBox  poninted by self.ptr
botahamec commented 2 years ago

@gftea According to the comment, it is being used to drop the value, if needed. Just keep in mind that dropping the value doesn't free the memory that it's in.

gftea commented 2 years ago

After the value drop, it should be uninitialized, we should not access it after that, so I think we should deallocate first before dropping ptr

botahamec commented 2 years ago

If you deallocate first, then how are you going to access the value so you can drop it? You don't have permission to use that part of the memory anymore. Besides, you don't have to access the value to deallocate memory. All you need is the pointer to where it was.

gftea commented 2 years ago

it is being used to drop the value, if needed. Just keep in mind that dropping the value doesn't free the memory that it's in.

sorry, I guess I did not understand above answer. Now if I understand it correctly, calling ptr::read(self.ptr) is to make sure trigger drop of all nested fields in value pointed by self.ptr , then use deallocate to free the memory pointed by self.ptr

botahamec commented 2 years ago

That's mostly correct. ptr::read is used to call the drop method of the value, if it implements Drop

gftea commented 2 years ago

after re-reading https://doc.rust-lang.org/nomicon/destructors.html, I think it will be more clear to explain further below