self is a local variable that always becomes invalid by the end of the function. In the first function, the *const i32 is pointing at that local variable, and so it is pointing at garbage after the function completes. It's a dangling pointer, and it is always invalid to dereference it at the call site.
In the second function, self is a reference to something that exists outside of the function. And the *const i32 is pointing at that same thing which is outside of the function. You never create a reference or pointer to the self variable in this case, you just effectively return a copy of one that already exists. How long the returned pointer is valid to dereference depends on what is going on at the call site.
struct Length(i32,*const i32);
pub fn from_ptr(&self) -> i32{
// SAFE: Length drop then i32 drop too!!
unsafe{self.1.read()}
}
When you move the Length around, the address where the i32 is changes, but the value of the *const i32 does not change, so this doesn't work like you seem to think it does.
There's a problem with the unsafe block in E1. The lifetime of v: &i32 in _new is unrestricted, so its address may or may not be valid at the time of from_ptr.
By the way, if you meant to create a self-referencing struct (i.e. the pointer points to an address inside Length, which I guess you want to be its i32 field) then I read that it requires using Pin to prevent the Length from being moved. I'm not really familiar with that, but I'll drop a link to the docs
And your current code is not self-referencing, E1's pointer points to wherever v points to (can be in main's stack frame, on the heap via &*b where b is a Box<i32>, etc), and E2's pointer points within _new's stack frame allocation.
It works differently.
simple ref is save value in stack and suply ref to it.
but box is different. it reserve ptr. change value under this ptr. after all it save the ptr to another stack.
and if it was deref it will take the value under this ptr. and save it in another stack.
so in ref case it would fixed the addr
but in the box ptr case the address can be change if it was allocated and deref_ed .