Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens in memory when ownership is transferred out of a box?

Does the variable s in print_struct refer to data on the heap or on the stack?

struct Structure {
    x: f64,
    y: u32,
    /* Use a box, so that Structure isn't copy */
    z: Box<char>,
}

fn main() {
    let my_struct_boxed = Box::new(Structure {
        x: 2.0,
        y: 325,
        z: Box::new('b'),
    });
    let my_struct_unboxed = *my_struct_boxed;
    print_struct(my_struct_unboxed);
}

fn print_struct(s: Structure) {
    println!("{} {} {}", s.x, s.y, s.z);
}

As I understand it, let my_struct_unboxed = *my_struct_boxed; transfers the ownership away from the box, to my_struct_unboxed, and then to s in the function print_struct.

What happens with the actual data? Initially it is copied from the stack onto the heap by calling Box::new(...), but is the data some how moved or copied back to the stack at some point? If so, how? And when is drop called? When s goes out of scope?

like image 628
mallwright Avatar asked Jan 07 '20 12:01

mallwright


People also ask

How does ownership work in Rust?

The ownership of a variable follows the same pattern every time: assigning a value to another variable moves it. When a variable that includes data on the heap goes out of scope, the value will be cleaned up by drop unless ownership of the data has been moved to another variable.

What are owned types in Rust?

When we talk about ownership in Rust, we generally mean – a variable owns a value. As we assign the same value between variables, we move the value, changing the owner. While this is true for Rust Owned types, the behavior is different for Rust References (also known as Borrowed types).

When does the transfer of ownership of a property take place?

However, the general rule is that the transfer of ownership depends upon the intention of the parties to the contract. The parties may fix any time for the transfer of ownership from the seller to the buyer.

Why is it necessary to determine the transfer of ownership?

It is necessary to determine the time at which the ownership of the goods is transferred to the buyer. Secs. 18 to 24 of the Indian Sale of Goods Act 1930 deal with the rules for the transfer of ownership which determine the time at which the ownership of the goods is transferred from the seller to the buyer.

When ownership of goods is transferred to the buyer?

In case of sale of unascertained goods, the ownership is transferred to the buyer as and when the goods are identified and are set apart for the purpose of delivering to the buyer. The ownership in case of unascertained goods is transferred to the buyer only on the fulfillment of the following two conditions:

How does it decide where to free memory?

It uses the ownership model to decide where to free memory; when the owner goes out of scope, the memory is freed. What are the stack and the heap? The stack and heap are both memory storage segments that are available for your code to use at runtime.


1 Answers

The Structure data in my_struct_boxed exists on the heap and the Structure data in my_struct_unboxed exists on the stack.

Therefore naïvely speaking (no compiler optimizations), a move or copy operation when dereferencing (*) your Box will always involve copying of the data. On the borrow-checker/static-analysis side, since the Copy trait is not implemented for Structure, this represents a transfer of ownership of the data to the my_struct_unboxed variable.

When you call print_struct, another copy would take place that would copy the bits in memory representing your Structure from the local variable to the function's arguments call-stack. Semantically, this again represents a transfer of ownership into the print_struct function.

Finally when print_struct goes out of scope, it drops the Structure which it owns.


Reference: std::marker::Copy

Excerpt

It's important to note that in these two examples, the only difference is whether you are allowed to access [your variable] after the assignment. Under the hood, both a copy and a move can result in bits being copied in memory, although this is sometimes optimized away.

Note the last part "this is sometimes optimized away". This is why the earlier descriptions were simplified to assume no compiler optimizations i.e. naïve. In a lot of cases, the compiler will aggressively optimize and inline the code especially with higher values for the opt-level flag.

like image 62
sshashank124 Avatar answered Oct 29 '22 23:10

sshashank124