IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Fortran Discussion :

Problème de modules


Sujet :

Fortran

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 29
    Points
    29
    Par défaut Problème de modules
    Bonjour à tous,

    Je suis loin d'être un pro en fortran, et en ce moment j'essaye de comprendre comment fonctionne les modules. Ce faisant, je suis tombé sur un problème dont je ne comprends pas l'origine. A titre de test, j'ai écrit ce petit programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    module mod1
    implicit none
    integer n
    double precision, allocatable :: u(:)
    end module mod1
     
    module mod2
    use mod1
    implicit none
     
    contains	
      subroutine blague(m)
              implicit none
              integer m,i
     
              m=2*n
              !write(*,*) 'bip'
              allocate(u(m))
              do i=1,m
                   u(i)=i           
              enddo
              deallocate(u)
         end subroutine blague
     
    end module mod2
     
     
    program test_allocate
    use mod1
    use mod2
    implicit none
     
    integer nn,j,m
     
    nn=2
    do n=1,nn
         call blague(m)
         write(*,*) (u(j),j=1,m)
    enddo
     
    end program test_allocate
    Or lorsque je compile et exécute, il me sort ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    0. 0.
    1. 2. 3. 4.
    Chose amusante, lorsque je lui fais afficher le 'bip' dans la subroutine 'blague', il me donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    bip
    1. 2.
    bip
    1. 2. 3. 4.
    Comment est-ce possible ? J'ai essayé différentes configurations, avec des 'interface' et autres, mais j'ai toujours le même problème. Je compile avec g95 sans aucune option sous cygwin. Je pense qu'il y a un truc que je n'ai pas bien pigé à propos des interfaces explicites...
    Merci d'avance pour votre aide.

    P.S. : je ne vous soumets pas ce problème juste pour m'amuser , je suis en train d'écrire un programme plus gros qui aura cette structure.

  2. #2
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    Salut

    La syntaxe de tes modules est bonne, tu pourrais cependant n'en faire qu'un seul en mettant blague dans mod1 ... mais si tu t'exerce ...

    Pour ce qui est de ton erreur je pense qu'elle est liée au deallocate. Dans blague tu deallocates u alors que tu veux imprimer ce qu'il contient par la suite. Je saurais pas t'expliquer avec des mots juste mais c'est comme si tu "supprimais ta variable"

    Le programme suivant fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    module mod1
    implicit none
    integer n
    double precision, allocatable :: u(:)
    end module mod1
     
    module mod2
    use mod1
    implicit none
     
    contains
      subroutine blague(m)
              implicit none
              integer m,i
     
              m=2*n
              allocate(u(m))
              do i=1,m
                   u(i)=i           
              enddo
              write(*,*) (u(i),i=1,m)
             deallocate(u)
         end subroutine blague
     
    end module mod2
     
    program test_allocate
    use mod1
    use mod2
    implicit none
     
    integer nn,j,m
     
    nn=2
    do n=1,nn
         call blague(m)
    enddo
     
    end program test_allocate
    Le fait que ça marche avec bip est un peu bizare mais souvent observer (avec "ok" aussi ). En fait quand tu imprime quelque chose il y a une histoire d'accés mémoire qui fait qu'il enregistre ailleurs et donc se souvient du contenu des variables ... mais j'avoue que c'est un peu flou pour moi !

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 29
    Points
    29
    Par défaut
    Merci de ta réponse, malheureusement ça ne règle pas vraiment mon problème . En effet, à l'avenir dans mon programme j'aurai besoin d'utiliser le tableau u dans le programme principal pour faire des opérations dessus, et le réinjecter dans d'autres subroutines. J'ai peur que s'il ne parvienne pas à m'afficher correctement u à l'écran, les résultats qu'il me donnera par la suite seront faux...

    Pour résumer, as-tu une idée de comment faire passer proprement u, dont la dimension est recalculée à chaque fois dans blague, à l'intérieur du programme principal ?

  4. #4
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    Je vois deux possibilités :

    1) ne pas utiliser de tableau dynamique.
    Tu pourrais définir une dimension maximum de ton tableau u. Ensuite dans blague tu as la dimension à utiliser et tu n'utilises que la partie du tableau qui t'intéresse. Il faut juste que tu pense à vérifier que tu vas utiliser une dimension plus petite que le max que tu as définit.

    2) Faire 2 subroutines de plus qui allocate et deallocate u. Tu met celle qui allocate u avant blague et celle qui le deallocate après blague et après tout ce que tu veux faire avec u.

    Ceci dis tout ça est un peu lourd ... je vois pas trop l'intérêt pour un tableau de dimension 10 ! Pourquoi veux tu faire un deallocate de u directement ? Ou alors tu te sert de u dans ta subroutine blague, si tu appelle d'autre subroutine depuis la subroutine blague elles pourront sans problème utiliser u !

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Bonjour,

    Comme te l'a signalé Ladgalen, tu ne dois pas désallouer u() dans blague si tu souhaite t'en servir par ailleurs.

    Vu que justement tu veux te servir de u() en dehors de sa routine d'initialisation, mais que tu veux également pouvoir le réinitialiser un certain nombre de fois, je te proposerai plutôt de modifier ta routine 'blague' comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
      subroutine blague(m)
              implicit none
              integer m,i
     
              m=2*n
              ! Allocation de u()
              if (allocated(u)) then
                deallocate(u)
                allocate(u(m))
              else
                allocate(u(m))
              endif
              do i=1,m
                   u(i)=i           
              enddo
     
         end subroutine blague
    En clair, lorsque l'on exécute 'blague', on teste si 'u' est déjà alloué; si oui, c'est que ce n'est pas la première fois que l'on passe par 'blague' et il faut d'abord désallouer u() avant de le réallouer.
    Ainsi, une fois l'exécution de 'blague' terminée, u() est toujours alloué (et initialisé) et est donc accessible/utilisable pour toutes routines/fonctions utilisant le mode 'mod2'.

    Bonne continuation.

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 29
    Points
    29
    Par défaut
    Bonjour,

    D'abord merci de vos réponses.
    @Ehouarn : Si j'utilise la subroutine telle que tu l'as écrite, la dimension de u ne va pas changer à chaque appel de blague, puisque tu ne feras l'allocation qu'une seule fois, à la première itération.
    @Ladgalen : 1/ Effectivement, je peux comme ceci, je cherchais une solution plus élégante qui ne m'oblige pas à faire ce genre de check.
    2/ Je vais essayer ça ce soir, je verrais ce que ça donne.
    Et effectivement tu as raison pour m=10 c'est complètement inutile. Mais mon vrai programme est beaucoup plus gros et prendra des tableaux de 10000, 100000 valeurs.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 29
    Points
    29
    Par défaut
    Argh non Ehouarn, j'avais mal lu... Ca semble être effectivement la solution à mon problème. Je teste ça de suite !

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 29
    Points
    29
    Par défaut
    Merci, effectivement ça fonctionne (oui je sais j'ai mis du temps à re-tester ). Mais je reviendrai sûrement avec une autre question à la con...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème chargement module apache
    Par tom79 dans le forum Apache
    Réponses: 1
    Dernier message: 05/03/2008, 12h04
  2. [Delphi 7 et 5] Problème de module Base de données
    Par riadmega dans le forum Débuter
    Réponses: 1
    Dernier message: 25/11/2007, 11h26
  3. problème de module menu jlomenu
    Par nemo666 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 11
    Dernier message: 23/04/2007, 22h51
  4. Problème du module login lors du changement de mot de passe
    Par MIC94 dans le forum Wildfly/JBoss
    Réponses: 1
    Dernier message: 31/08/2006, 11h51
  5. [Oracle9i]Problème création module d'écoute
    Par Gidrah dans le forum Oracle
    Réponses: 2
    Dernier message: 25/04/2006, 19h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo