You can't really return an array without using dynamic memory allocation (malloc/free).
It's been a couple of decades since I was into this stuff, but I don't think that's quite right.
Of course you're referring to arrays which are local variables, and the fact that the array name is syntactically equivalent to pointer-to-array-element. Returning a pointer to a local variable is not safe.
Others have already pointed out that if you have an array which is not allocated on the stack, you can return that just fine. Well, strictly you return the pointer to the array, but it remains valid after the return executes.
IIRC there is [at least] one situation where you can declare a local variable allocated on the stack, and return that safely. If you declare a struct containing an array, you can assign instances of that struct to each other and that structure assignment does a shallow copy of the memory occupied by the struct. If the struct contains an array, the array elements are copied, too. In other words, this is safe:
sprintf_s(result.text, sizeof(result.text), "Me");
I'm not suggesting this is a good design to solve the original problem, but it's a way to return an array.