2 votes

quels types de problèmes l'absence de désallocation peut-elle entraîner ?

Je rencontre actuellement un problème dans lequel j'obtiens

*** glibc detected *** ./efit: free(): invalid next size (fast): 0x00000000006127f0 ***

avec les informations habituelles sur la carte mémoire et le backtrace qui accompagnent un glibc Je n'arrive cependant pas à trouver la cause de ce problème. il semble que (pratiquement) tout mon programme soit terminé au moment où cela se produit. une chose que j'ai lue en ligne est que cela pourrait être dû à un manque de désallocation.

J'ai exécuté le programme sans désallouer quelques-uns de mes tableaux (j'avais l'impression que la désallocation pouvait provoquer des fuites de mémoire, mais que cela n'affecterait que les performances et l'efficacité du programme pendant qu'il s'exécute).

Est-il possible que mes exécutions précédentes du programme sans désallouer mes tableaux reviennent me hanter dans le sens où il y a de la mémoire non libérée des exécutions précédentes sur laquelle j'essaie d'écrire ?

Si ce n'est pas le cas, je suis complètement déconcerté par cette erreur. Des indices sur l'endroit où je devrais commencer à chercher et/ou sur la façon dont je devrais déboguer pour trouver l'erreur ?

pour ce que cela vaut, j'utilise gfortran pour compiler

EDIT : les options de compilation n'ont pas permis d'identifier directement ce problème au départ, mais elles m'ont aidé à l'atténuer. j'utilisais une variable entière. iat pour iat=1,natoms dans un do et quelques lignes plus loin, il s'est dit iat décrivait un autre nombre entier dans les limites de la 1,natoms Lorsque j'ai corrigé quelques-uns des avertissements listés par vos options de compilation, cette erreur s'est transformée en une description beaucoup plus claire de l'erreur : Fortran runtime error: Index '7' of dimension 1 of array 'isnormed' above upper bound of 6 .

Qu'est-ce qui a empêché cette erreur de se produire la première fois ? Les seules modifications que j'ai apportées à reach et qui m'ont été signalées par les avertissements de compilation sont les suivantes read(fout, '(a)'), line100' to read(fout, '(a)') line100' (en supprimant la virgule) et en modifiant l'ancien style de description des caractères character*100 line100 vers les plus récents character(100) line100 descriptions.

1voto

Gene Points 20184

Ce message ne concerne pas l'échec de la désallocation. Il indique que le tas est corrompu. Il y a de nombreuses façons dont cela peut se produire, mais oublier de libérer un tableau n'en fait pas partie. Le plus probable, s'il s'agit d'un code Fortran, est qu'un tableau a été mal déclaré.

Le message est généré lorsque glibc effectue un contrôle de cohérence. Ainsi, le quand La date d'apparition du message (début ou fin de l'exécution) n'a pas d'importance, si ce n'est que vous savez que la corruption s'est produite à un moment donné (mais cela peut être n'importe quel moment) avant l'apparition du message.

Un tas corrompu signifie que les réponses générées par votre programme peuvent être parfaitement correctes ou complètement inutiles. Vous devez vous débarrasser de ce message.

(j'avais l'impression que la désallocation pouvait provoquer des fuites de mémoire, mais que cela n'affectait que les performances et l'efficacité du programme en cours d'exécution).

Il s'agit d'un retour en arrière. Les fuites de mémoire se produisent lorsque la désallocation est no fait.

La meilleure solution consiste à utiliser un outil tel que valgrind conçu pour détecter et signaler en détail les problèmes de tas.

1voto

M. S. B. Points 19509

Une erreur commise lors d'une exécution précédente de votre programme ne peut pas avoir d'incidence sur l'exécution suivante. Le système d'exploitation charge une nouvelle version de l'exécutable et lui fournit de la mémoire. Le transfert d'informations n'est possible que si le programme écrit des informations dans un fichier et les lit lors de l'exécution suivante.

La mémoire est automatiquement désallouée par le système d'exploitation lorsque le programme se termine. En outre, pour Fortran >=95, les tableaux allouables qui sont locaux à une procédure sont automatiquement désalloués par Fortran lorsque la procédure revient.

Il est très probable que vous ayez un problème d'utilisation de la mémoire qui corrompt les structures internes décrivant la mémoire utilisée par votre programme. En Fortran, cela est possible si les arguments de l'appelant et de l'appelé ne correspondent pas, si l'indexation dépasse la fin d'un tableau ou si des pointeurs sont utilisés. Utilisez-vous des pointeurs ? Si ce n'est pas le cas, il est généralement facile de se prémunir contre les deux premiers cas à cette époque. Placez vos procédures dans des modules et "utilisez" ces modules. Cela permettra au compilateur de vérifier la cohérence des arguments. Compilez avec l'option de vérification des indices au moment de l'exécution. Cela vous permettra de savoir si vous indexez au-delà de la fin d'un tableau et si vous le stockez dans une autre mémoire.

Avec gfortran, essayez les options de compilation suivantes : -O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace. Si certains de ces avertissements sont trop nombreux, le plus important pour ce problème est fcheck=all, ou encore plus restreint, fcheck=bounds.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X