Yes, it is educated that way. However, for the case requires some scratch space, dynamic allocations can be easier to manage, less error prune and with less overall memory usage (you don't need to preallocate worst case amount).
That's why even people knew, many C APIs still return dynamic allocated objects or simply let you inject malloc / free if you want more control.
This is a roundabout way to say: if you aspired to provide APIs with zero dynamic allocation, go ahead. But if you find yourself struggling with more complicated code as a result, think about just letting a little bit dynamic allocations may help.
That's why even people knew, many C APIs still return dynamic allocated objects or simply let you inject malloc / free if you want more control.
This is a roundabout way to say: if you aspired to provide APIs with zero dynamic allocation, go ahead. But if you find yourself struggling with more complicated code as a result, think about just letting a little bit dynamic allocations may help.