What you are trying to do is normally done in two steps.
1. Creating a dynamic array of pointers to structs with malloc. 2. Creating structs for each array element and assigning their address to each array element with malloc.
Then your method to free will work.
Other option:
Just use one malloc and free the whole block.
Always learn from history, to be sure you make the same mistakes again...