Here's how to think about ownership in Rust. First, realize that Rust has basically the same memory model as C/C++. C/C++ has three big sources of memory trouble: "how big is it", "who owns it", and "who locks it". C/C++ provides little help in dealing with those issue. Rust locks down all those problem. Mostly through compile time checks.
Ownership in Rust starts out simple. There's single-ownership, and multiple-ownership with reference counting. The latter comes in two flavors, with and without concurrency locking. Reference counting works roughly the way you think it should.
In addition to ownership, there's "borrowing". This usually means creating a local reference to something. The local reference must have a scope that doesn't outlive the thing being borrowed. That makes borrowing safe. Borrowing is a compile-time thing with no run-time representation. Borrowed objects with reference counts don't need reference count updates on the borrowed reference, which speeds things up a lot. Borrowing in Rust is cheap and easy, and should be done frequently.
When a reference to something is passed into a function, the compiler needs to know if it's being borrowed, or whether ownership is being handed off to the function. The default is to borrow; for more complex situations, there's special lifetime syntax. A similar issue appears when a function returns a reference. Returning a reference is complicated - is it a new object, or a borrowed reference to an input object? Creating new objects in functions and returning them should be avoided if possible. It's a Rust idiom to create the object in the caller and pass it into a function to be modified.
Single ownership can be handed off to another owner. This, after some controversy, is the default action for the "=" operator. (Using "<-" for ownership transfer probably would have been better.) Such a handoff invalidates the variable that gave up ownership, and that variable can't be used again. For some types, though, you get a copy instead. For other types, you have to explicitly ask for a copy. This part of the language is kind of ugly.
Rust has the concept of "mutability". This is just the inverse of "const". Since immutability is the default, you write "mut" in a lot of places.
Programs in Rust need more design effort than in some other languages. You need to plan out who's going to own what, and who gets to change what. "Agile" types may find this troublesome. The payoff is that once the program has compiled, whole classes of errors have been eliminated.