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 :

utilisation delete[] pour tableaux dynamiques 2D et 3D


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Février 2004
    Messages
    197
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 197
    Par défaut utilisation delete[] pour tableaux dynamiques 2D et 3D
    Bonjour,
    Mon code alloue dynamiquement de la mémoire à des tableaux 2D ou 3D. Je voudrais détruire les tableaux après utilisation, mais je ne sais pas comment faire.

    Voici le programme principal (simplifié)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main()
    {
    double *tableau1D, **tableau2D, ***tableau3D;
    int dim1 = 10, dim2 = 20, dim3 = 30;
     
    Initialize_1D(dim1, &tableau1D);
    Initialize_2D(dim1, dim2, &tableau2D);
    Initialize_3D(dim1, dim2, dim3, &tableau3D);
     
    return(0);
    }
    Les fonctions d'allocation de mémoire
    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
     
    void Initialize_1D(int dim1, double **R)
    {
    *R = new double[dim1];
    }
     
    void Initialize_2D(int dim1, int dim2, double ***R)
    {
    *R = new double*[dim1];
    for (int i=0; i<dim1; i++)
    {
    (*R)[i] = new double[dim2];
    }
    }
     
    void Initialize_3D(int dim1, int dim2, int dim3, double ****R)
    {
    *R = new double**[dim1];
    for (int i=0; i<dim1; i++)
    {
    (*R)[i] = new double*[dim2];
    for (j=0; j<dim2; j++)
    {
    (*R)[i][j] = new double[dim3];
    }
    }
    }
    J'ai quelques idées pour le tableau 1D mais je sèche complètement pour les tableaux 2D et 3D.
    Auriez-vous quelques suggestions ?

  2. #2
    Membre éprouvé
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    189
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Par défaut
    Il faut détruire en premier ce que tu as construit en dernier.

    Ici, si tu as fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Alloc (1)
    boucle
      Alloc (2)
    Tu vas devoir faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    boucle
      Desalloc (2)
    Desalloc (1)
    Je te laisse l'honneur de faire le code.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Attention.

    Du pointeur de pointeur (de pointeur) c'est du bordel monstre en perspective.
    Imagine qu'un objet lance une exception lors de sa construction. Tu appercois le merdier pour désallouer ce qui l'a été ?

    Pas moi

    je te conseille donc de te tourner vers ldes conteneurs mettant en oeuvre le RAII comme les std::vector (et les std::vector de vector ...) ou vers d'autre solution plus spécialisé si tes tableaux représente des matrices ou ce genre de choses.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    De plus, les indirections, c'est aussi efficace que l'utilisation d'un pointeur simple avec un stride (machin[i + j * taille_x]), mais c'est moins rapide si ton tableau est très grand (parce que plus costaud sur le cache).

  5. #5
    Membre confirmé
    Inscrit en
    Février 2004
    Messages
    197
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 197
    Par défaut
    Je ne comprends pas bien vos reponses !! ... C'est quoi le RAII ?

    En fait j'ai deja un code assez compliqué et gros (environ 5000 lignes) basé sur ce système de pointeurs de pointeurs... Ca marche très bien et je n'aurais pas le courage de changer de principe pour allouer les tableaux...

    Voila ce que j'ai écrit pour désallouer un tableau 2D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Freememory_2D(int dim1, double ***R)
    {
    for (int i=0; i<dim1; i++)
    {
    delete[] (*R)[row];
    }
    delete[] (*R);
    }
    J'appelle la fonction avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Freememory_2D(dim1, &tableau_2D);
    Ca compile sans warnings et pas d'erreur a l'execution...

    Mon problème c'est que si je code ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Freememory_2D(int dim1, double ***R)
    {
    for (int i=0; i<dim1; i++)
    {
    delete[] R[row];
    }
    delete[] R;
    }
    Ca marche aussi, pas de warning du compilateur et ca s'execute sans pb !!
    Quelle est la bonne methode ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par jejerome Voir le message
    - c'est quoi une indirection ?
    C'est le fait d'avoir un pointeur de pointeur.

    Citation Envoyé par jejerome Voir le message
    - c'est quoi le RAII ?
    C'est l'idée d'utiliser des objets qui s'allouent et se désallouent tous seuls. Quelqu'un qui aurait mauvais esprit appelerait ça du "VB Envy", mais en fait, c'est assez pratique, car ca t'évite de t'ennuyer avec les détails de la gestion mémoire...

    Citation Envoyé par jejerome Voir le message
    Voila ce que j'ai écrit pour désallouer un tableau 2D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Freememory(int dim1, double ***R)
    {
    for (int i=0; i<dim1; i++)
    {
    delete[] (*R)[row];
    }
    delete[] (*R);
    }
    Ca compile sans warnings et pas d'erreur a l'execution...

    Mon problème c'est que si je code ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Freememory(int dim1, double ***R)
    {
    for (int i=0; i<dim1; i++)
    {
    delete[] R[row];
    }
    delete[] R;
    }
    Ca marche aussi, pas de warning du compilateur et ca s'execute sans pb !!
    Quelle est la bonne methode ?
    La première... A priori ton tableau c'est *R, R c'est juste un pointeur sur ce tableau... La seconde est fausse, mais comme souvent avec les désallocation fautives, elle ne se voit pas forcément tout de suite. Si maintenant tu compiles en utilisant un outil de vérification des erreurs mémoire, je pense qu'il se rappelera à ton souvenir...

    Francois

  7. #7
    Membre éprouvé
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    189
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Par défaut
    1) Si il n'y a pas de blocs mémoires contiguë assez grand.

    2) Le problème c'est que tu ne peux pas dans toutes les applications te contenter de laisser planter bêtement le programme. Tu pourrais avoir certaines informations cruciales à sauvegarder.

    Dans certain cas aussi tu peux peut-être gérer autrement la mémoire ( ne pas charger telle information par exemple ) .

    3) Tu ne sais pas dans quel environnement l'application va être exécutée. Tu peux très bien avoir un client qui a un vieux PC, ou toute autre situation exotique.

    Et on ne sait pas : peut-être que dans quelques années les PC standard auront moins de mémoire et dédiront beaucoup au Cloud. A ce moment là, qqn qui voudra utiliser ton application ( en local ) sera bien embêtée et ne saura pas comment corriger l'erreur.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par jejerome Voir le message
    J'ai quelques idées pour le tableau 1D mais je sèche complètement pour les tableaux 2D et 3D.
    Auriez-vous quelques suggestions ?
    Si tu alloues tes tableaux avec des new, tu dois les désallouer avec des delete[]

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    double *tab=new  double[n];
    delete[] tab;
    En 2D, c'est exactement, pareil, mais tu dois, comme hiura l'a dit, désallouer dans l'ordre inverse.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    double **mat=new double*[n];
    for(int i=0;i<n;i++) mat[i]=new double[p];
     
    for(int i=0;i<n;i++) delete[] mat[i];
    delete[] mat;
    La raison est que si tu fais delete[] mat d'abord, tu n'as plus accès aux mat[i], et tu ne peux plus les désallouer.

    En 3D, ou au delà, c'est exactement pareil.

    Côté librairie standard, si tu travailles sur des données numériques, et des matrices, je te conseille vivement de regarder les valarray (les vector de vector pour representer les matrices, c'est pas une bonne idée, à mon avis...)

    Francois

Discussions similaires

  1. Utiliser Merise pour créer un site web dynamique
    Par joannq dans le forum Merise
    Réponses: 1
    Dernier message: 09/11/2009, 16h39
  2. Réponses: 1
    Dernier message: 16/05/2008, 17h53
  3. Comment utiliser fread pour remplire 1tableau dynamique
    Par MClover dans le forum Débuter
    Réponses: 9
    Dernier message: 13/04/2008, 15h38
  4. Réponses: 5
    Dernier message: 06/09/2006, 13h15
  5. [Tableaux] Script de recherche pour site dynamique
    Par clemsouz dans le forum Langage
    Réponses: 7
    Dernier message: 12/05/2006, 16h31

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