Je travaille avec un code Fortran qui contient des pointeurs de tableau; Selon la saisie de l'utilisateur, ils pourraient être définis pour pointer sur un autre tableau avec l'instruction d'affectation Ceci crée un problème pour libérer la mémoire à la fin du code, car dans le premier cas, je veux juste Y a-t-il un moyen simple de distinguer les deux cas? P>
Merci! P> => code> ou ils peuvent être directement alloués avec l'instruction
allouer code>. p>
nullify code> le pointeur, tandis que dans le second cas, je dois
offliger < / code> pour empêcher une fuite de mémoire. Le problème est que dans les deux cas
associé code> renvoie vrai i>, donc je ne sais pas comment dire quel cas je suis sans garder la trace de cela manuellement. Puisqu'il y a beaucoup de points de tableau, je préférerais éviter de devoir le faire. P>
3 Réponses :
Cela ressemble à un désordre horrible. Je suppose que vous avez quelque chose comme ceci: et votre problème est la partie détruite. Si comme @ Ian-Bush souligne, vous pouvez vérifier si quelque chose est associé à autre chose, mais cela signifierait que vous devez comparer le pointeur avec toutes cibles possibles et vous prétendez que vous en avez beaucoup. P> Une chose que vous pourriez essayer, mais cela est probablement encore pire une idée, est d'essayer de distribuer et d'utiliser son une méthode beaucoup meilleure serait probablement Pour remplacer vos pointeurs de tableau avec des types qui ont à la fois le pointeur et un drapeau de la manière dont il était associé. p> aucune de ces suggestions ne vous aidera pas alors Un autre pointeur à A code> pointe vers
B code>, alors que vous souhaitez code> nullify code>, car vous devez conserver
B code>. Mais si
a code> ne pointe pas sur
b code>, et que vous seul
nullify code> it, vous obtenez une fuite de mémoire. P>
STAT = CODE> argument factice pour vérifier si le tableau a effectivement fonctionné. Veuillez noter que c'est un terrible hack, et je ne le suis que de travailler sur Intel, pas sur gfortran, mais ici ne fait rien: p>
a code> puis essaie de le détruire fort>. Dans ce cas, je suggère vraiment de repenser votre conception de votre projet entière. P> p>
Merci beaucoup pour votre réponse. Vous avez complètement compris la situation. Je suis également arrivé à la conclusion que votre dernière méthode avec le drapeau supplémentaire est la seule voie à suivre (rien d'autre ne pointera les pointeurs, donc pas de problèmes là-bas). J'espérais pouvoir éviter cela, mais il semble qu'il n'y ait vraiment pas d'autre moyen.
Comment compliqué est votre structure de données? C'est-à-dire combien de pointeurs sont associés simultanément à une seule cible à un moment donné? La norme Fortran est complètement silencieuse lorsqu'il s'agit de référencer la cible instanciée à l'aide de l'instruction Si vous avez accès à un compilateur FORTRAN moderne (2008+), le module suivant pourrait être utile; FYI, les variables déclarées dans un module héritent automatiquement de l'attribut allouer code>, c'est-à-dire qu'elle ne spécifie pas un mécanisme pour s'assurer que la mémoire cible est libérée lorsque tous les points de vue sont libérés. dissocié. La collection de déchets intégrée est précisément pourquoi l'attribut
allouatable code> est préféré sur le pointeur code> attribue 99,9% du temps. Dans l'événement rare que vous devez absolument utiliser un pointeur et que sa cible est attribuée dans un autre sous-programme, puis a transmis la chaîne d'appels à une procédure différente, la possession de pointeur devient un cauchemar.
Enregistrer code>. La cible
foo code> est une variable de module privé et
ref_counter code> garde la trace du nombre de pointeurs associés à
foo code>. En surchargeant la relocalisation code> code> Nous pouvons annuler en toute sécurité NULLIFY, NULLIFY + DealLocate. avec
appelerallocate (quelque_ptr, dealloc_stat) code> p>
J'utilise une certaine construction similaire, mais à mon avis, la pleine puissance de la référence à compter que vous obtenez uniquement lorsque vous créez un nouveau type dérivé de référence et surcharger les missions et appliquer les finalisations (de la même manière que votre NULLIFY_PTR et POINT_AT_FOO.
Peut-être que ce sera utile à quelqu'un. J'ai poussé à Github ma simple mise en œuvre de comptage de référence qui vous permet de suivre les références aux variables. Lorsque le nombre de références est 0, l'objet est automatiquement distribué. Link https://github.com/ladaf/fortran-refcount
Il est basé sur des idées de papier Voiture - Comptage de référence Implémentation dans Fortran 95/2003 et réserver Conception de logiciels scientifiques: la manière orientée objet . P>
La référence L'objet lui-même stocke un pointeur à un autre objet REFPTR code> qui stocke le pointeur sur les données elles-mêmes et le nombre de références qui l'indiquent. Les affectations sont surchargées de manière à ce que le nombre de références soit mis à jour. La finalisation des objets de référence soustrait des comptes de référence selon les besoins. P>
type(ref) :: a, b
a = 42
print *, "a:", a%value(0)
!this does not copy the value, it points the reference
b = a
print *, "b:", b%value(0)
!sets a to point to something new, b still points to 42
a = 2.3
Par "à la fin du code", quelle distance est-ce que vous voulez dire? Tout au long de l'exécution, je me soucie de fuites de mémoire, etc., mais à la fin de mon programme, il n'est plus ma responsabilité de s'assurer que tout soit rangé.
Je ne suis pas sûr de comprendre ce que vous voulez dire ... Je devrais sûrement viser que toute la mémoire allouée à être traitée avant que le programme se termine?
Je voulais dire que le programme (horrible):
allouatable i; allouer (i); fin code>. Je ne ressens pas le moindre peu de culpabilité de ne pas avoir de
de manière code> là-bas. Il y a des moments où je veux être responsable de la localisation, mais pas ici. Est la prémisse de votre question qu'il devrait y avoir une déclaration code> code>? Mon premier commentaire était juste pour établir cela.
Ah Désolé, oui je me sens coupable! Il devrait y avoir un
deallocate code> pour chaque
allouer code>. Si je fais:
entier, pointeur :: i (:); allouer i (5); annuler (i); fin code> alors je finirai avec un espace qui n'est pas distribué et également inaccessible au code.
Juste pour être clair, de peur que quiconque trébuche à travers cette question et se gênent aussi confus que moi - il n'y a absolument pas besoin de la mémoire explicitement libre, que ce soit en utilisant
offliger code> ou
nullify code> la fin d'un programme. À moins que votre O / S ne soit cassé, il allait récolter toute la mémoire allouée au programme lorsque le programme se termine. Ce serait une question différente si la souci de SOP était de récolter la mémoire à un autre point pendant l'exécution. Vous souhaitez également garder à l'esprit que les dernières éditions de la norme Fortran garantissent la classification lorsqu'un objet alloué est hors de portée.