Seus professores estão levantando um ponto importante. Infelizmente, o uso do inglês é tal que não tenho certeza do que eles dizem. Deixe-me responder à pergunta em termos de programas que não sejam de brinquedo, que têm certas características de uso de memória e com os quais trabalhei pessoalmente.
Alguns programas se comportam bem. Eles alocam memória em ondas: muitas alocações de pequeno ou médio porte seguidas por muitas liberações, em ciclos repetidos. Nestes programas, os alocadores de memória típicos funcionam muito bem. Eles aglutinam blocos liberados e, no final de uma onda, a maior parte da memória livre está em grandes blocos contíguos. Esses programas são bastante raros.
A maioria dos programas se comporta mal. Eles alocam e desalocam memória mais ou menos aleatoriamente, em uma variedade de tamanhos, de muito pequenos a muito grandes, e retêm um alto uso de blocos alocados. Nestes programas, a capacidade de coalescer blocos é limitada e, com o tempo, eles acabam com a memória altamente fragmentada e relativamente não contígua. Se o uso total da memória exceder cerca de 1,5 GB em um espaço de memória de 32 bits, e houver alocações de (digamos) 10 MB ou mais, eventualmente uma das grandes alocações falhará. Esses programas são comuns.
Outros programas liberam pouca ou nenhuma memória, até que parem. Eles alocam memória progressivamente durante a execução, liberando apenas pequenas quantidades, e então param, momento em que toda a memória é liberada. Um compilador é assim. Então é uma VM. Por exemplo, o tempo de execução .NET CLR, ele próprio escrito em C ++, provavelmente nunca libera memória. Por que deveria?
E essa é a resposta final. Nos casos em que o programa é suficientemente pesado no uso de memória, gerenciar a memória usando malloc e free não é uma resposta suficiente para o problema. A menos que você tenha sorte o suficiente para lidar com um programa bem comportado, você precisará projetar um ou mais alocadores de memória personalizados que pré-alocam grandes blocos de memória e então sub-alocam de acordo com uma estratégia de sua escolha. Você não pode usar o Grátis de forma alguma, exceto quando o programa for interrompido.
Sem saber exatamente o que seus professores disseram, para programas em escala de produção, provavelmente, eu ficaria do lado deles.
EDITAR
Terei uma chance de responder a algumas das críticas. Obviamente, o SO não é um bom lugar para postagens desse tipo. Só para ficar claro: tenho cerca de 30 anos de experiência escrevendo este tipo de software, incluindo alguns compiladores. Não tenho referências acadêmicas, apenas minhas próprias contusões. Não posso deixar de sentir que as críticas vêm de pessoas com experiências muito mais restritas e curtas.
Vou repetir minha mensagem principal: balancear malloc e free não é uma solução suficiente para alocação de memória em grande escala em programas reais. Bloco coalescente é normal, e ganha tempo, mas é não o suficiente. Você precisa de alocadores de memória sérios e inteligentes, que tendem a agarrar a memória em pedaços (usando malloc ou qualquer outro) e raramente liberam. Esta é provavelmente a mensagem que os professores de OP tinham em mente, que ele interpretou mal.