Если вы хотите выпустить все сразу, вы должны выделить все сразу.
Простое ручное решение, если вы заранее знаете общий размер, который вам нужен, состоит в том, чтобы распределить все по частям и проиндексировать в зависимости от ситуации. Если вы заранее не знаете размер, вы можете использовать realloc для увеличения памяти, если вы только обращаетесь к ней, проиндексированной из исходного указателя, и нигде не храните дополнительные указатели.
При этом прямое распределение и освобождение - простое решение, и ошибиться труднее, чем альтернативы. Если цикл освобождения не вызовет у вас реальных трудностей, я буду придерживаться того, что у вас есть.