I don't know if C is necessarily the best language to familiarize users with these concepts. Rust makes users grapple with the implications of explicit memory management but does so in a way that is far less dangerous at runtime than C (at least in many cases). So maybe figuring out how to reason about pointers and lifecycles and ownership in an explicit way in order to get a Rust program to compile is better than messing around with code that segfaults and does weird things until it happens to start working properly.
But I still think there is some value to hands-on experimentation. Concepts like "primitives are passed by value, but objects are passed by reference" in a higher-level language might seem like arcane trivia to a beginning programmer, but someone who has played around with the same idea in C (or another language where this sort of thing is reified) might be better positioned to understand the underlying rationale.