There is a misconception in your thinking, perhaps you lack better understanding about stack and heap.
If the information is on stack really you can’t trust that it will be there when the function ends, but it is a little rarer you create a pointer to the stack.
But if it’s allocated to heap, you can return a pointer to this allocated area smoothly. The area remains available even when the function is finished. This is the main reason to use the heap.
You are even correct in your thinking from the point of view of code organization. The most correct is the function that needs information to allocate the memory needed for the object, pass it to the function that will fill this object and then when it comes back to it to release this memory.
Nothing prevents you allocating in a function that will fill and return, but it is asymmetrical, because it is responsible for allocating and does not release (nor could it in this case), this gives margin for errors. Well-built functions require consumers to deliver their already-allocated memory. Even if you need a relocation within it, this is less problematic. Interestingly, this is basically the so-called dependency injection.
So from a technical point of view you can do as you’re asked, but any good programmer would do it the way you’re thinking, you’re right.