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 :

allocation dynamique en mémoire d'un tableau


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 88
    Par défaut allocation dynamique en mémoire d'un tableau
    Bonjour encore !

    j'ai un problème d'allocation de mémoire d'un tableau que je dois lire dans un fichier, voici mon code tout simple :

    num_zo = nombre de zone lue.
    Ni*Nj*Nk = nombre de lignes du tableau T
    num_var = nombre de colonnes du tableau t
    le tableau est lu sur Ni*Nj*Nk lignes et sur num_var colonnes.

    Pour chaque num_zo, Ni, Nj,Nk varient :

    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
    integer, dimension(:),allocatable :: Ni,Nj,Nk,ifin
    real*8, dimension(:,:),allocatable :: T
     
    allocate(Ni(num_zo))
    allocate(Nj(num_zo))
    allocate(Nk(num_zo))
     
    do i=1,num_zo
    read(7,*) i1,i2,i3
    Ni(i)=i1  ! On récupère les dimensions pour chaque zone
    Nj(i)=i2
    Nk(i)=i3
    ifin(i)=Ni(i)*Nj(i)*Nk(i) ! ifin(i) determine le nombre de lignes lues dans le fichier)
    !allocate(T(num_var,ifin(i)) ! c'est ici mon problème
    do j=1,ifin(i)
    read(7,*) T(1:num_var,j)
    enddo
    enddo
    le problème est la taille du tableau T ou je stocke des valeurs pour chaque zone.
    car quand je mets : allocate(T(num_var,ifin(i)), j'ai une erreur : attempting to allocate already allocated array

    avez vous une astuce pour eviter cette erreur?

    Merci

  2. #2
    Membre émérite Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Par défaut
    c'est normal:
    tu alloue DANS la boucle Do donc à la première itération, pas de problème, il alloue le tableau, mais dès la seconde, problème: il cherche à re-allouer ton tableau!
    de plus tu peux simplifer Nj,ni,nk:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    integer, dimension(:,:),allocatable :: N
    allocate N(num_zo,3)
    par exemple.

    tu n'alloue pas non plus ifin
    je te suggère une lecture en deux fois:
    - la première pour déterminer la taille totale
    - la second pour la lecture des données

    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
     
    integer, dimension(:,:),allocatable :: N
    integer, dimension(:),allocatable :: ifin
    real(kind=8), dimension(:,:,:),allocatable :: T
     
    allocate(N(num_zo,3))
    allocate(ifin(num_zo))
     
    do i=1,num_zo
       read(7,*) N(i,1),N(i,2),N(i,3)
       ifin(i)=N(i,1)*N(i,2)*N(i,3) 
       do j=1,ifin(i)
         read(7,*)
       enddo
    end do
    !allocation du tableau global:
    allocate(T(num_zo,numvar,maxval(ifin)))
    rewind(7)
    do i=1,num_zo
       read(7,*)! on saute la ligne
       do j=1,ifin(i)
         read(7,*)T(i,1:Numvar,j)
       enddo
    end do
    cependant cette approche consomme beaucoup de mémoire inutile surtout si tes zones sont de taille très différente: on est obligé d'alloué comme si toutes les zones avaient la même taille et donc obligé d'allouer le tableau à la taille de la plus grande zone!

    il faudrait chercher le moyen de ranger plus intelligemment les données dans le tableau, genre une lecture de données brute adjoint à un tableau d'adressage!

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 88
    Par défaut
    Je vais essayer de faire un rewind, ça devrait marcher, cela étant, mon programme est super moche, j'ai plein de rewind partout mais la fin justifie le moyen !!

    Merci encore!

  4. #4
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 88
    Par défaut
    en ce qui concerne l'allocation du tableau T :

    allocate(T(num_zo,numvar,maxval(ifin))
    pour le maxval(ifin), est ce qu'il ne vaudrait mieux pas définir une nouvelle variable, qui serait le résultat de la somme de tout les ifin pour chaque zone :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    somme =0 ! initialisation de la variable
    do i=1,ifin(num_zo)
    somme= somme+ifin(i)
    enddo
    et puis de faire :
    allocate(T(num_zo,numvar,somme)
    car je voudrais avoir la taille exacte du tableau.

  5. #5
    Membre émérite Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Par défaut
    je n'y avais pas pensé, tu as num_zo zones, de tailles respective ifin(
    tu dois donc lire Sum(ifin) lignes de numvar variables

    d'où une alloc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    allocate(T(numvar,sum(ifin))
    et là, tu as exactement la bonne taille de tableau

    en revanche pour acceder à tes données:

    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
     
    function accesdata(izone,iligne,numvar,ifin,T)
      implicit none
      integer, intent(in) :: izone,iligne,numvar
      integer,dimension(:),intent(in)::ifin
      real(kind=8),dimension(:,:),intent(in)::T
      real(kind=8),dimension(numvar)::accesdata
    !
      integer debut
      if (izone==1) then
        debut=1
      else
        debut = sum(ifin(1:i-1))
      end if
      accesdata= T(:,debut+iligne)
      return
    end function accesdata
    afin de pouvoir accèdé à la ligne 'iligne' de la zone 'izone' dans le bloc de données T

  6. #6
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 88
    Par défaut
    Merci de ton idée, j'avais oublié la fonction sum(valeur(i)) :arf:

    Je repose la même question pour une autre lecture :



    seulement le tableau que je lis, doit etre lu de la manière suivante :
    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
     
    read(7,*) (((T(num_zo,num_var_,Ni,Nj,Nk),i=1, Ni), j=1,Nk), k=1,Nk)
     
     
    !mon premier problème se pose quand je veux récupérer les Ni,Nj,Nk pour !chaque num_zo (chaque zone):
    ! num_var designe le nombre de variable qui est pareil pour n'importe quel !num_zo
     
    integer, dimension(:),allocatable :: Ni,Nj,Nk
    real*8, dimension(:,:),allocatable :: T
     
    allocate(Ni(num_zo))
    allocate(Nj(num_zo))
    allocate(Nk(num_zo))
     
    do i=1,num_zo
    read(7,*) i1,i2,i3
    Ni(i)=i1  ! On récupère les dimensions pour chaque zone
    Nj(i)=i2
    Nk(i)=i3
     
    ! il faut lire ensuite le tableau T
     
    ! il faudrait un do j=1, n_lignes
    !read(7,*) seulement je ne connais pas sa taille, et donc combien de lignes il !faut lire
    ! enfin, on peut trouver le nombre de ligne par :
    !  n_ligne= (Ni(i)*Nj(i)*nk(i) )/5  ! il existe 5 valeurs de T par ligne
    ! quoique  c'est problematique car il faut vérifier que n_ligne est divisible par 5
    ! ( cas de la dernière ligne avec moins de 5 valeurs)
    ! enddo
     
    enddo
     
    allocate(T(num_zo,num_var,produit(Nbi),produit(Nbj)),produit(Nbk))
    en ce qui concerne la taille des produit(Ni) et produit(Nj),je suis entrain de me casser la tête dessus !



    est ce que vous auriez une idée?

  7. #7
    Membre émérite Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Par défaut
    En fait c'est axactement le même tableau que précédement!!!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    allocate(T(numvar,sum(ifin))
    avec la même lecture!!!

    seulement, on va changer la fonction d'accès (je te laisserai faire l'éventuelle fonction d'écritue: c presque pareil )
    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
    function accesdata2(T,izone,ivar,i,j,k,Ni,Nj,Nk,)
      implicit none
      integer, intent(in) :: izone,ivar,i,j,k,Ni,Nj,Nk
      real(kind=8),dimension(:,:),intent(in)::T
      real(kind=8) accesdata
    !
      integer debut,iligne
      integer ii,jj,kk
    !
      if (izone==1) then
        debut=1
      else
        debut = sum(Ni(1:izone-1)*Nj(1:izone-1)*Nk(1:izone-1))
      end if
      iligne=(i-1)*Ni(izone)+(j-1)*Nj(izone)+k
      accesdata= T(ivar,debut+iligne)
      return
    end function accesdata2

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

Discussions similaires

  1. probleme d'allocation dynamique de mémoire
    Par Blo0d4x3 dans le forum C
    Réponses: 2
    Dernier message: 13/03/2007, 07h53
  2. Allocation dynamique de mémoire : Limitations ?
    Par rulianf dans le forum C++
    Réponses: 5
    Dernier message: 22/03/2006, 17h03
  3. Allocation dynamique de mémoire
    Par cd090580 dans le forum Autres éditeurs
    Réponses: 7
    Dernier message: 12/11/2005, 11h17
  4. [VC++/ASM] Allocation dynamique de mémoire ?
    Par Magus (Dave) dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 21/12/2004, 15h05
  5. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31

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