Confused about drop memory,why does it can work?

i am test the clear memroy,
frist,i know the std::mem::drop not really drop memory,just take the ownership,it drop when out of the scope and if impl the Drop trait,the func "drop" will execute before really drop.
i wanna know when the variable was drop,what will be happen when i still use the static borrow.
so i write this test for verify:

pub struct Test {
    temp: &'static String,
}

impl Drop for Test {
    fn drop(&mut self) {
        println!("drop Test");
    }
}
fn main(){
    let mut t: Option<Test> = None;
    unsafe {
        let str = String::from("test");
        let str_ptr = str.borrow() as *const String;
        t = Some(Test {
            temp: str_ptr.as_ref().unwrap(),
        });
    }
    println!("res {:?}", t.as_ref().unwrap().temp);
}

the result:

res:"test"
drop Test

it's work,but why? the "str" and "str_ptr" was drop before "t",the "temp" of "t" should point to a invalid head address,but the it work.
so,the compiler know still have other place use it,so do not drop "str"?
it confused me.
is there some one know the reson?
thanks for help!

When you use unsafe to transmute the lifetime, the compiler can no longer help you in verifying the correctness of your code. That said, the code you posted doesn't compile at all, so I can't give more details.

2 Likes

It just happens to be working. You're referencing invalid memory, which is UB - Undefined Behavior. The behavior is not defined so the compiler can generate arbitrary code for it. It may crash the process. It may silently corrupt some completely unrelated portion of the memory. It may launch a nuclear missile to the mars. And of course, it may work, for this time, though not guaranteed.

2 Likes

Lifetimes don't do anything. They never generate any code. They're only used to check correctness at compile time, but you've used unsafe to bypass the check.

3 Likes

I got:

res "h���"
drop Test

:grin:

6 Likes

You seem to be assuming that freeing memory automatically "clears"/zeros it or does something with it. It doesn't – that would be an unnecessary pessimization. Freeing a memory region merely marks it as re-usable at any time, this is why it's invalid to use it, because it may be reused by someone else. It doesn't have to be reused nor written to in all cases.

1 Like

u can change println! to dbg!,then can print right :slight_smile:

thanks for share,i am sorry,i write error code,i have fix "fn main{}" to "fn main(){}",now it will be compile.
i understand what mean is that use unsafe,the compiler will not help me to check,but it still can execute.i mean the code should not can be print,but it does.
i mean,maybe give me a execute error code is more sense.

well,i think it's a good explain,but still not very thoroughly? i do not know,hear like gc? tag what is invaild,than check the point to this,if none,drop?

UB must not happen. You're telling the compiler "I know what I'm doing, so stop complaining". It should be noted, that unsafe doesn't turn off the all compiler errors. It just turns off errors for very specific things and assumes you did everything correct for these specific things. That's why it's called unsafe, because you can break your whole program in very weird (undefined) ways, if you don't know what you're doing.

2 Likes

yes,if i do not use unsafe,compiler do not allow my code pass.
i mean,i bypass the check,but runtime,it not should be print right?because the "str" is already drop,
the 'static point(Test's temp) is invalid.it should be occur runtime error like c++?

No, there's no guarantee that incorrect unsafe code results in any runtime errors. Just like in C++, it can silently give wrong results or corrupt some data without warning. Results can be random.

Whether use-after-free is caught depends on many factors, and there are lots of cases when it won't, so you can't rely on that. You might catch a few more invalid cases with Rust's MIRI (cargo miri), but it's also not a guarantee.

That's why safe Rust is so important. Without unsafe you do have a guarantee that all errors will be caught every time.

2 Likes

No. The behavior is undefined. It's not true that the code shouldn't work, and it's not true that it should work. The code does not make sense, so it might do anything. The word "should" is wrong here because "the code should X" means you were expecting X and you got Y. But you cannot expect undefined behavior to be anything in particular.

2 Likes

Excuse me? I don't understand what you are trying to say there.

1 Like

wow,i am little scare with unsafe now, hear like many things is no guarantee and random,maybe i mistake with unsafe at the start.
i thinking maybe i should check my program,change unsafe code to safe.
thanks for your share :slight_smile:

1 Like

sorry about that,i mistake what u say,sorry!
do u mean memory multiplexing?because Real-time memory application and memory destruction is a little performance loss?

No, I didn't mean memory multiplexing.

I was trying to say that freeing dynamically allocated memory isn't required (or expected) to zero or otherwise overwrite that piece of memory immediately. Freeing a heap-allocated buffer only means giving it back to the OS so that it can give it to some other function, process, etc. later. That re-allocation may happen much later, or it may not happen at all. In either case, if you erroneously access the memory after it was freed, you will still see its original contents, but the point is that you can't insist on that, because it may have been overwritten in the meantime. And there's a difference between "may have been overwritten" and "it was surely overwritten".

2 Likes

oh,this time i get your point.
I think you have a point there,so many time,use unsafe is not a good idea,because as u said?
yeah,should be care for when use unsafe.especially if it's a big project, review code is kill somebody,hahah ^_^.
to be honest,i have write unsafe in many place at my project,Although there is no problem yet,but for now,i think It is necessary to review unsafe code ,or change to safe code.
thank your share,your share is very valuable for me!

yeah,Although your description is abstract, it makes sense,thank u

thanks for everyone!
Rust community always make me excited,people are very friendly and enthusiasm.
i hope one day, i can learn rust more better for i can help others,just like u guys :slight_smile:

2 Likes