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

 C++ Discussion :

[debutant nul] libération mémoire tableaux dynamiques


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Points : 10
    Points
    10
    Par défaut [debutant nul] libération mémoire tableaux dynamiques
    Bonjour,

    Voilà une question très con certainement... mais il faudrait bien que j'arrive à faire fonctionner les tableaux dynamiques une bonne fois pour toute au lieu de galérer à chaque fois à me demander ce que j'ai fait de pas bien.

    Désolée par avance si vous trouvez que ma question a sa réponse dans la FAQ ou dans n'importe quel cours de C++...mais voilà, chez moi, ya toujours un problème avec la mémoire, même quand j'ai l'impression d'avoir fait comme dans les exemples qu'on trouve partout.

    Voilà mon "problème" :

    Je veux créer un tableau dynamique avec "new". Ecrire dans le tableau. Et enfin, libérer la mémoire que j'ai alloué à mon tableau. Rien de compliqué... la base la plus simple qu'il soit. Mais je suis tellement nulle que je me fais engueuler lors de l'exécution du programme.


    Je vous met mon code :
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    1 #include <iostream>
    2 #include <fstream>
    3
    4 using namespace std;
    5
    6 int main()
    7 {
    8  ifstream DATA;
    9  DATA.open("picsoleil.dat");
    10  if (!DATA)
    11    {
    12      cout<<"Error opening DATA file"<<endl;
    13      return 1;
    14    }
    15
    16 
    16  int n, cpt;
    17  double x, y;
    18
    19  DATA>>n;
    20
    21  double *tabfreq = new double[n];
    22  if (tabfreq == NULL) return 1;
    23  double *tabampl = new double[n];
    24  if (tabampl == NULL) return 1;
    25
    26  cpt = 0;  do{
    27    DATA>>x>>y;
    28    tabfreq[cpt] = x;
    29    tabampl[cpt] = y;
    30    cpt++;
    31  }while(DATA.eof()==0);
    32
    33 cout<<"hfurehf"<<endl;
    34
    35  // params : tableau des freq, tableau des amplitudes, nombre de points
    36
    37  struct data 
    38  {
    39    double *freq, *ampl;
    40    int npts;
    41  };
    42
    43  data *params;
    44
    45  params->freq = tabfreq;
    46  params->ampl = tabampl;
    47  params->npts = n;
    48
    49
    50  for(int i = 0; i<n; i++)
    51    {
    52      cout<<"tabfreq["<<i<<"] = "<<tabfreq[i]
    53	  <<"\ttabampl["<<i<<"] = "<<tabampl[i]<<endl;
    54    }
    55
    56  delete [] tabfreq;
    57  delete [] tabampl;
    58 
    59  DATA.close();
    60 }
    Je sais pas ce qu'il y a comme erreurs... mais quand j'exécute mon prog, il fait tout sans problème mais je suppose qu'il foire au moment de la libération de la mémoire et dit :
    *** glibc detected *** essai_asupp: double free or corruption (!prev): 0x09abf178 ***
    ======= Backtrace: =========
    /lib/libc.so.6[0x4752aa68]
    /lib/libc.so.6(__libc_free+0x78)[0x4752df6f]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x478ef6c1]
    etc...

  2. #2
    Membre confirmé Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Points : 496
    Points
    496
    Par défaut
    Ton code a l'air plutôt bon, mais trop dangereux, je m'explique :
    tu ne peut pas faire confiance à intégrité de ton fichier, si g bien compris le premier chiffre est egal aux nombre de couple de fichier. Donc a chaque fois que tu fais un ptr[index] tu dois tester que ton index ne dépasse pas.
    Bien sur je te conseille l'utilisation des vecteurs à la place (sauf si c pour apprendre ).
    Test aussi ton programme avec un fichier minimaliste que tu génères toi même avec un editeur ( voir Driving Test Developpement )
    Et force toi a appliquer une règle de codage: pas bien les DATA en majuscule.

    Bon chance et n'hésite pas a riposter si sa merde encore.

  3. #3
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    La struct définie au milieu de la fonction n'est pas du plus bel effet non plus
    Essaye d'éviter à moins que tu ai une très bonne raison de le faire.

    Essaye de mettre un point d'arrêt conditionnel dans ta boucle, je soupçonne cpt > n

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Même si ton fichier est bien écrit, ta variable cpt vaudra n (ce qui est en dehors des bornes du tableau) si il y a une ligne vide à la fin du fichier (un retour chariot de trop).
    Il y a aussi la variable params qui pose problème. Il faudrait faire un new avant de changer ses champs.

  5. #5
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 382
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 382
    Points : 20 453
    Points
    20 453
    Par défaut
    Je suis sceptique sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    do{
    DATA>>x>>y;
    tabfreq[cpt] = x;
    tabampl[cpt] = y;
    cpt++;
    }while(DATA.eof()==0);
    Tu affectes les tableaux alors que DATA.eof n'est pas encore rencontré.
    Mieux vaut utiliser while(!DATA.eof()){.....}

  6. #6
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Non. Mieux vaut utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while (data >> x >> y) {
       ...
    A moins d'aimer écrire deux fois la lecture, ou le test.

  7. #7
    Membre averti Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Points : 358
    Points
    358
    Par défaut
    Erreur si simple que du coup apparemment personne l'a vue ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct data 
    38  {
    39    double *freq, *ampl;
    40    int npts;
    41  };
    42
    43  data *params;
    44
    45  params->freq = tabfreq;
    46  params->ampl = tabampl;
    47  params->npts = n;
    Ca manque de new sur params .....

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Erreur si simple que du coup apparemment personne l'a vue ....
    Ah non, remonte un peu plus haut

    Il y a la variable params auquel il manque un new.

    Il y a la lecture du fichier qui n'est pas protégée contre des dépassements de tableau.

    Mais depuis le temps, j'ai l'impression que notre ami ne retrouve plus le chemin du forum

  9. #9
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,
    Citation Envoyé par themadmax Voir le message
    ( voir Driving Test Developpement )
    J'imagine que tu voulais parler de Test Driven Development ?
    (c'est au cas où l'ami retrouve le forum et cherche à se renseigner dessus )

    MAT.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Je suis désolée de ne repondre que maintenant.... ma freebox et son alimentation sont HS... du coup, je ne peux répondre qu'au boulot...

    Je ne vous garanti pas que j'ai compris tout ce que vous m'avez dit... mais je vais faire un effort.

    themadmax : Pourquoi c'est pas bien DATA en majuscules ?
    Ah, les vecteurs ? En fait je n'ai jamais rien fait avec des vecteurs... Va falloir que je me documente.
    Pour ce qui est d'utiliser un programme minimaliste, c'est déjà un peu ce que je fais...
    Mon fichier comprend 94 lignes (ce qui est trèèèès peu comparé aux centaines de milliers de lignes que je dois traiter en temps normal... 405 000 pour être précise) et il représente un pic d'intensité centré autour d'une fréquence donnée (que je dois trouver mais je n'en suis pas encore là). J'ai rajouté la première ligne qui est effectivement égale au nombre de couples {frequence-amplitude} car j'ai besoin de connaitre cette valeur pour faire mes tableaux. Si vous avez d'autres idées pour éviter ça, je suis preneuse ! (avec des mots simples,.... suis pas douée moi)
    A priori, le premier chiffre de mon fichier est toujours juste car c'est moi qui l'ai rentré à la main en ayant pris soin de vérifier que je ne me suis pas trompée.


    NiamorH : Pourquoi ce n'est pas bien de mettre la structure en plein milieu du programme ? Faut-il que je la sorte du main ?
    Ok pour le point d'arrêt conditionnel, après tout, on n'est jamais assez prudent.

    aoyou : Merci pour les explications, effectivement, je n'avais pas pensé au retour charriot qu'il pourrait y avoir en plus.
    Pour ce qui est de la variable param, je n'ai pas encore beaucoup travaillé dessus (l'excuse !) et surtout c'est la première fois que je crée une variable telle que params... Concrètement, le new, je dois le mettre où ? (je vous avais dit que je suis débutante hein ) C'est la même chose que ce que j'ai écris pour mes tableaux ?
    Je met un truc de ce genre là ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data *params = new data ?????
    Kujara : Je dois être la seule qui trouve que cette erreur n'est pas simple du tout. Va falloir que je continue de me documenter. A ce propos, est-ce que vous auriez un livre à me conseiller ???

    Matt007 : J'ai retrouvé le chemin du forum !

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    En fait, je ne sais pas du tout si ce que je fais est juste... Je m'explique.
    Ca serait plus simple si vous me donniez votre avis sur ma manière de voir les choses que je vais expliquer. Là, vous n'avez eu qu'un tit bout de programme mais sans connaitre l'objectif que je souhaite atteindre.

    En fait, je veux pouvoir utiliser une fonction de la GSL de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f(const gsl_vector *v, void *params);
    Et il se trouve que dans void *params, je dois mettre mon tableau contenant mes fréquences, mon tableau contenant mes amplitudes et le nombre d'éléments de ces tableaux (mais je me demande s'il n'est pas possible de retrouver ce nombre d'éléments avec une fonction toute faite. un sizeof() pourrait faire ça ???).
    D'où la structure que j'ai créée avec mes deux tableaux et le nombre d'éléments et le pointeur du type de ma structure... Est-ce que ça peut fonctionner comme ça ? Ou bien est-ce que je fais trop compliqué ?

    J'espère que mes explications sont claires....

    En tout cas, merci pour votre aide, maintenant je vais aller changer tout ce que vous m'avez déjà conseillé de changer.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Bon, j'ai fait les changements suivants :

    1- Declaration de ma structure en dehors du main (me confirmer si c'est là qu'il faut la mettre ou non, je n'ai pour le moment rien trouvé sur l'emplacement de la déclaration d'une structure dans un programme)

    2- Je n'ai plus mis de majuscules à DATA excepté la première --> Data

    3- Pour ma boucle while sur mon fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     cpt = 0;
      while(Data >> x >> y)
        {
        tabfreq[cpt] = x;
        tabampl[cpt] = y;
        cpt++;
        if (cpt >= n) {cout<<"compteur a atteint la limite"<<endl; break;}
        }
    Par contre, je n'arrive pas à savoir s'il faut que je mette cpt <= n ou cpt < n pour ma condition d'arrêt. Les deux fonctionnent sans problème apparemment... Le premier arrête ma boucle car le test est fait avant celui de la boucle et pour le deuxieme cas, la boucle s'arrête d'elle même (je ne sais pas si je suis claire...).


    4- J'ai ajouté un new lors de ma déclaration de *params :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data *params = new data;
    et j'ai mis en fin de programme
    Et je n'ai plus de messages d'erreur lors de l'execution du programme : en deux mots --> Ca marche !

    Donc merci à vous tous !!
    Mais c'est pas fini, car maintenant je vais essayer de manipuler un peu ma structure pour apprendre comment ça marche.

    J'attend quand même votre avis sur l'utilisation de mon pointeur *params pour l'entrer en tant que paramètre dans ma fonction de la GSL.

    Faut encore que je regarde comment fonctionnent les vecteurs au cas où.


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

Discussions similaires

  1. Libération mémoire d'objet dynamique
    Par Romvaillant dans le forum C++
    Réponses: 17
    Dernier message: 13/10/2007, 22h46
  2. [Debutant] déclaration de class et libération mémoire
    Par personaprimonpseudo dans le forum Débuter
    Réponses: 5
    Dernier message: 14/05/2007, 14h13
  3. libération des tableaux dynamiques
    Par franckgar dans le forum Langage
    Réponses: 4
    Dernier message: 19/04/2006, 20h49
  4. Réponses: 3
    Dernier message: 14/03/2006, 05h19
  5. [debutant] : Allocation de mémoire dynamique
    Par sam.fet dans le forum Langage
    Réponses: 5
    Dernier message: 15/02/2006, 14h58

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