If you're using a language with garbage collection, it's obviously not going to result in segfaults, but you can still run into logic errors when part of your code assumes that it's done dealing with a piece of data and another part has a different idea. More generally, if your object is stored in multiple places in your code, you have to remember to clean up all references to it properly, in all the different states your system can be in, and your compiler can't verify you're doing that correctly without a borrow checker.
> but you can still run into logic errors when part of your code assumes that it's done dealing with a piece of data and another part has a different idea.
Mostly I think this is sufficiently handled by not mutating shared state as a practice. However, since Rust has mutable borrows, it seems to me that you're still in danger of running into this.
For example, in C#, you need to Dispose() objects that are logically no longer used, to have them properly cleaned up. Using an object after it's disposed typically results in an ObjectDisposedException. This isn't as bad as a segfault, but ultimately it's still a crashing bug in the app - and solving it requires figuring out who needs to call Dispose when - i.e. figuring out the lifetime.
End result: This app spends about 30% CPU time on malloc/strdup/free.
In Rust, you simply wouldn't have this design in the first place because it's so easy to avoid. In C, it's super intrusive to fix once it's obvious this is a bottleneck.
Though this isn't necessarily a fuzzy concept of ownership, just more of a pain-to-deal-with thing.