Le problème est principalement un artefact historique, pas une impossibilité de mise en œuvre.
Le code de construction de la plupart des compilateurs C est tel que le compilateur ne voit que chaque fichier source à la fois; il ne voit jamais tout le programme à la fois. Lorsqu'un fichier source appelle une fonction à partir d'un autre fichier source ou d'une bibliothèque, le compilateur voit uniquement le fichier d'en-tête avec le type de retour de la fonction, pas le code réel de la fonction. Cela signifie que lorsqu'une fonction renvoie un pointeur, le compilateur n'a aucun moyen de savoir si la mémoire sur laquelle le pointeur pointe doit être libérée ou non. L'information à décider qui n'est pas montrée au compilateur à ce moment-là. De son côté, un programmeur humain est libre de rechercher le code source de la fonction ou la documentation pour savoir ce qu’il faut faire avec le pointeur.
Si vous examinez des langages de bas niveau plus modernes tels que C ++ 11 ou Rust, vous constaterez qu'ils résolvent principalement le problème en rendant la propriété de la mémoire explicite dans le type du pointeur. En C ++, vous utiliseriez un à la unique_ptr<T>
place d'un simple T*
pour conserver la mémoire et la unique_ptr<T>
vérifie que la mémoire est libérée lorsque l'objet atteint la fin de la portée, contrairement à l'objet ordinaire T*
. Le programmeur peut transmettre la mémoire de l'un unique_ptr<T>
à l'autre, mais il ne peut jamais y en avoir qu'un qui unique_ptr<T>
pointe vers la mémoire. Il est donc toujours clair à qui appartient la mémoire et quand elle doit être libérée.
Le C ++, pour des raisons de compatibilité ascendante, permet toujours la gestion manuelle de la mémoire à l’ancien style et donc la création de bogues ou de moyens de contourner la protection d’un unique_ptr<T>
. Rust est encore plus strict dans la mesure où il applique des règles de propriété de la mémoire via les erreurs du compilateur.
En ce qui concerne l’indécidabilité, le problème d’arrêt, etc., oui, si vous vous en tenez à la sémantique C, il n’est pas possible de décider pour tous les programmes quand la mémoire doit être libérée. Cependant, pour la plupart des programmes actuels, et non des exercices académiques ou des logiciels bogués, il serait absolument possible de décider quand libérer ou non. Après tout, c’est la seule raison pour laquelle l’homme peut déterminer quand libérer ou non.