El problema es principalmente un artefacto histórico, no una imposibilidad de implementación.
La forma en que la mayoría de los compiladores de C construyen código es para que el compilador solo vea cada archivo fuente a la vez; nunca ve todo el programa a la vez. Cuando un archivo fuente llama a una función desde otro archivo fuente o una biblioteca, todo lo que ve el compilador es el archivo de encabezado con el tipo de retorno de la función, no el código real de la función. Esto significa que cuando hay una función que devuelve un puntero, el compilador no tiene forma de saber si la memoria a la que apunta el puntero necesita liberarse o no. La información para decidir que no se muestra al compilador en ese momento. Un programador humano, por otro lado, es libre de buscar el código fuente de la función o la documentación para averiguar qué debe hacerse con el puntero.
Si observa lenguajes de bajo nivel más modernos como C ++ 11 o Rust, encontrará que en su mayoría resolvieron el problema al hacer explícita la propiedad de la memoria en el tipo de puntero. En C ++, usaría un en unique_ptr<T>
lugar de un plano T*
para mantener la memoria y unique_ptr<T>
se asegura de que la memoria se libere cuando el objeto llegue al final del alcance, a diferencia del plano T*
. El programador puede pasar la memoria de uno unique_ptr<T>
a otro, pero solo puede haber uno unique_ptr<T>
apuntando a la memoria. Por lo tanto, siempre está claro quién posee la memoria y cuándo debe liberarse.
C ++, por razones de compatibilidad con versiones anteriores, todavía permite la gestión de memoria manual de estilo antiguo y, por lo tanto, la creación de errores o formas de eludir la protección de a unique_ptr<T>
. Rust es aún más estricto ya que impone las reglas de propiedad de la memoria a través de errores del compilador.
En cuanto a la indecidibilidad, el problema de detención y similares, sí, si se adhiere a la semántica en C, no es posible decidir para todos los programas cuándo se debe liberar la memoria. Sin embargo, para la mayoría de los programas reales, no para ejercicios académicos o software con errores, sería absolutamente posible decidir cuándo liberar y cuándo no. Después de todo, esa es la única razón por la cual los humanos pueden decidir cuándo liberarse o no en primer lugar.