That makes a lot of sense. I do some embedded development, but when I dont, I tend to prefer heap just because my memory debuggers are much more capable working with heap memory.
In the case you show, foo would have to be a struct that doesn't contain pointers to additional allocated memory, but its a entirely valid use case and pattern.
Calling malloc and free, has a cost associated with it, that the stack doesn't. But stack can in some cases, like with recursion be scary to use, because you dont know where it ends. If malloc returns NULL you know you have found the end and can do something reasonable.
Thanks for you insight!