I'm not convinced it's "serious" --- thread-local-storage easily solves that.
Since this structure contains embedded pointers (including two that point to arrays of pointers), there could be quite a lot of things for the caller to call free() on (and in the right order).
Again the solution is simple: Allocate everything at once, so that free() need be called only once on the returned block.
In some ways I think the relative difficulty of using dynamic allocation in C compared to other languages is a good thing --- it forces you to think whether it's really necessary before doing so, and in many cases, it turns out not to be. That way encourages simpler, more efficient code. In contrast, other languages which make it very easy to dynamically allocate (or even do it by default) tend to cause the default efficiency of code written in them to be lower, because it's full of unnecessary dynamic allocations.