Indeed, the secret-sauce that you are looking for here is “references.”
The concept here is several levels above the concept that you see in “C,” this being of course the language in which Perl was implemented. A reference is, if you want to think of it this way, “a pointer to” a complete, self-describing Thing, that is also well-known to the Perl interpreter and fully part of the environment that it creates. Perl can look at a reference , and know everything that needs to be known about what it refers to. It knows how many references currently exist to that same thing, therefore it knows whether-or-not that object is eligible to be garbage-collected. The Perl language does not have the concept of a “structure,” in the C/C++ sense, but it does have the concept of a list, array, and hash.
The environment that has been created by the Perl interpreter is intended to focus upon providing an efficient solution to the same problem that one might use “pointers to structures” in bare-bones C to address, but to do so in a way that is much less reliant upon the program-in-question to “do everything in just the right way, or else.” There exist several layers of well-tested software that any Perl programmer can rely upon the existence of, that a C-programmer cannot. All of us here fully-understand both environments.