Create new instance in for loop got same pointer

Here's the situation, I was trying to create a vector of raw pointer to avoid using Rc and RefCell and make the code easier, so here's the sample code, how can I create new instance and store the pointer into the vector, why does this happen?

struct Foo{
    a: u64,
}

fn main() {
    for i in 0..2{
        let mut f = Foo{a:i};
        println!("{:?}", &mut f as *mut Foo);
        println!("{}",f.a);
    }
    let mut f1 = Foo{a:2};
    let mut f2 = Foo{a:3};
    println!("{:?}", &mut f1 as *mut Foo);
    println!("{:?}", &mut f2 as *mut Foo);
}

Yes? Why do you think this is a problem. Heck, if optimizations are turned on you may even see f have the same address as f1 or f2.

I just tried it and got f to be the same as f2 on my first run with optimizations (in release mode)

0x7fff69dd3e48
0
0x7fff69dd3e48
1
0x7fff69dd3e50
0x7fff69dd3e48
1 Like

Thanks for your quick response, but I think the pointers should point diffrent address.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=dcf4828877f417f0480a41984e5917f1

So the reason is the rust compiler optimizations make the new pointer point to the same address, is there a way to use raw pointer to archive this like C++ pointer, or using raw pointer in rust is a bad idea?
I just try not use Rc and RefCell pointer because that will need many borrow() and borrow_mut() code.

In your example, the Foo with the same addresses are created in a loop and then dropped at the end of the loop. They don't persist past the loop. If you had held on to those pointers past the loop, they would be dangling.

Doing anything useful with the pointers is going to require unsafe code, and unsafe code is the opposite of easier.

3 Likes

Thanks for your reply. I got it.

Not sure what you mean by that, because C++ pointers work in exactly the same way.

2 Likes

rustacean_1 might be thinking of creating objects on the heap with the new operator in C++.

The closest equivalent in safe Rust would be Box::new(Foo { a: 1 }). This allocates on the heap and returns a unique owning pointer, like modern C++ unique_ptr, but it can be transformed into a raw pointer for use in unsafe code. (Though I agree with the above comment that safe Rust is usually easier.)

3 Likes

Thanks for your reply, I got it.

I got it, thanks.