A questão é principalmente um artefato histórico, não uma impossibilidade de implementação.
A maneira como a maioria dos compiladores C constrói código é para que o compilador veja apenas cada arquivo de origem por vez; nunca vê o programa inteiro de uma só vez. Quando um arquivo de origem chama uma função de outro arquivo de origem ou de uma biblioteca, tudo o que o compilador vê é o arquivo de cabeçalho com o tipo de retorno da função, não o código real da função. Isso significa que quando existe uma função que retorna um ponteiro, o compilador não tem como saber se a memória que o ponteiro está apontando precisa ser liberada ou não. As informações para decidir que não são mostradas para o compilador nesse momento. Um programador humano, por outro lado, é livre para procurar o código fonte da função ou a documentação para descobrir o que precisa ser feito com o ponteiro.
Se você procurar por linguagens de baixo nível mais modernas, como C ++ 11 ou Rust, descobrirá que elas resolveram o problema principalmente ao tornar explícita a propriedade da memória no tipo de ponteiro. No C ++, você usaria um em unique_ptr<T>
vez de uma planície T*
para armazenar memória e unique_ptr<T>
garante que a memória seja liberada quando o objeto atingir o final do escopo, diferente da planície T*
. O programador pode unique_ptr<T>
passar a memória de um para outro, mas só pode haver um unique_ptr<T>
apontando para a memória. Portanto, é sempre claro quem é o dono da memória e quando ela precisa ser liberada.
O C ++, por motivos de compatibilidade com versões anteriores, ainda permite o gerenciamento manual de memória com estilo antigo e, portanto, a criação de bugs ou maneiras de burlar a proteção de um unique_ptr<T>
. A ferrugem é ainda mais rigorosa na medida em que impõe regras de propriedade da memória por meio de erros do compilador.
Quanto à indecidibilidade, o problema de interrupção e similares, sim, se você seguir a semântica C, não será possível decidir para todos os programas quando a memória deve ser liberada. No entanto, para a maioria dos programas atuais, não exercícios acadêmicos ou software de buggy, seria absolutamente possível decidir quando liberar e quando não. Afinal, essa é a única razão pela qual os humanos podem descobrir quando libertar ou não em primeiro lugar.