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 :

Creer un tableau dynamique


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 16
    Points
    16
    Par défaut Creer un tableau dynamique
    Bonsoir à tous,

    je travaille avec le builder C++ version 6.0
    voilà j'ai un petit soucis, j'ai crée un tableau statique, et maintenant que j'ai avancé dans mon travail, je me suis rendue compte qu'il fallait un tableau dynamique pour pouvoir le vider ne surtout pour ne pas fausser le reste de mon algo.

    Le new et delete sont expliqués dans la doc que j'ai trouvé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int* tab = new int[20];delete [] tab;
    mais mon tableau est une matrice de [7][2] au max, et je ne sais pas comment faire.

    en statique j'ai fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    float tab[7][2]; tab[j][0]=1-Distance;
                  tab[j][1]=j;
                  AFFICHAGE->Cells[0][j]=FloatToStr(tab[j][0]);
                  AFFICHAGE->Cells[1][j]=FloatToStr(tab[j][1]);
    et ça marche bien, mais en dynamique comment faire?
    comment dois je déclarer mon tableau en new!
    j'ai déjà cherché dans le help et sur google.... Merci bien

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Un float[7][2] est un tableau de tableaux : pour l'allouer, il faudrait faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    float **f=new float *[7];
    for(int i=0;i<7;i++) f[i]=new float[2];
     
    ...
     
    for(int i=0;i<7;i++) delete[] f[i];
    delete[] f;
    Le premier new crée les "lignes" du tableau, le second les alloue.

    Si tu as beaucoup de lignes, cela peut te faire un paquet de new. Un moyen de gagner du temps est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    float **f=new float *[7];
    f[0]=new float[14];
    for(int i=1;i<7;i++) f[i]=f[i-1]+2;
    En fait, tu alloues tout le tableau au début de la première ligne, et tu mets le début des lignes suivantes "à leur place".

    L'intéret c'est que ca se désalloue assez simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    delete[] f[0];
    delete[] f;
    mais aussi que tu peux, à partir de f[0] traiter le tableau comme si c'était un bête vecteur.

    Francois

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    Tout d'abord je vous remercie vraiment vraiment bcp de m'avoir répondus si clairement et si vite. Merci beaucoup

    bon,
    je ne sais pas si j'ai mal inséré la boucle, mais en tous les cas j'ai le même soucis que quand j'ai crée le tableau statique, les anciennes valeurs restent, et du coup bein, ça s'écrasent! donc, par exemple le tableau ne se remplissant en premier qu'à [4][2] , et le suivant est de taille [2][2] , comme résultat :les deux nouvelles lignes du [2][2]s'écrivent, mais les deux dernières de la matrice précédente [4][2]restent.

    voilà ce que j'ai fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    float **tab=new float *[7];
    for(int i=0;i<7;i++) tab[i]=new float[2];
     int n;for(int J=0;J<n;J++){........................}for(int i=0;i<7;i++) delete[] tab[i];
    delete[] tab;

    le tableau est toujours remplis, j'ai mis des messages d'erreurs pour tout voir, ça s'écrase.... pourquoi ça ne se vide pas lorsque J=n ?


    Merci pour votre attention

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Points : 214
    Points
    214
    Par défaut
    Une petite indentation sauve bien des heures de lecture.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    float** tab = new float*[7];
    for (int i = 0; i < 7; ++i) /* Changé i++ en ++i, cf FAQ. */
        tab[i] = new float[2];
     
    int n; // Son rôle ?
     
    for (int J = 0; J < n; ++J) /* Changé i++ en ++i, cf FAQ. */ {
        // ........................
    }
     
    for (int i = 0; i < 7; ++i) /* Changé i++ en ++i, cf FAQ. */
        delete[] tab[i];
    delete[] tab;
    le tableau est toujours remplis, j'ai mis des messages d'erreurs pour tout voir, ça s'écrase.... pourquoi ça ne se vide pas lorsque J=n ?
    Que fais-tu avec les "......" ?

    Si tu essayes d'afficher le tableau après les delete, tu peux tout à fait te retrouver avec les mêmes valeurs en mémoires, mais tu peux aussi faire planter ton application. Delete libère la mémoire, il ne la "supprime" pas.

    PS : je te conseille de jeter un œil aux std::vector. C'est très bien, surtout quand on débute.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    Merci ,

    puisque je veux utiliser d'abord le i avant de l'incrémenter, je laisse le : i++ .

    donc, la suppression n'est pas physique... j'ai compris. lol


    C bon, je vais faire avec alors....


    Merci beaucoup pour tout votre aide.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Je ne suis pas sur de comprendre le probleme... Ceci dit...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int n;
    for(int J=0;J<n;J++) {
    }
    Ca ne peut pas bien se passer : si aucune valeur n'est donnée à n, la boucle s'arrête quand?

    Un point à connaitre, c'est que new n'initialise pas la mémoire, il la réserve seulement... Quand je fais p=new int[3]; les trois entiers ainsi réservés p[0], p[1] et p[2] contiennent n'importe quoi...

    De même, delete[] n'efface pas les données, mais celles ci sont marquées comme "libres" ce qui fait que le programme peut les utiliser pour autre chose...

    Le i++ et le ++i, c'est autre chose... En fait, ++i augmente la valeur de i, et renvoie cette valeur incrémentée, alors que i++ renvoie l'ancienne valeur de i, et puis incrémente i. Du coup, i++ fait une copie, qui ici ne sert à rien, puisqu'on n'a pas besoin de la valeur retournée par i++... Donc, i++ est en théorie une instruction plus complexe, et éventuellement plus lente que ++i.

    Maintenant, pas de panique, sur un type natif comme des entiers (et en fait dans presque tous les cas rencontrés en pratique) le compilateur comprendra que l'on n'a pas besoin de cette valeur, la supprimera à l'optimisation, et i++ et ++i génèreront exactement le même code.

    Du coup, écrire i++ ou ++i, quand i est un entier, ca ne change pas grand chose, mais ca permet ces grands débats de fond, sans lesquels l'informatique ne serait pas tout à fait la même...

    Francois
    Dernière modification par Invité ; 12/05/2009 à 22h00.

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Points : 214
    Points
    214
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int n;
    for(int J=0;J<n;J++) {
    }
    Ca ne peut pas bien se passer : si aucune valeur n'est donnée à n, la boucle s'arrête quand?
    S'il a de la chance son compilateur va initialisé n à 0.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    d'acc...

    Merci de m'expliquer ainsi....


    en fait voilà mon 'n' ( je ne voulais pas vous agacer avec, mais c'est un tout petit entier le pauvre entre 1 et 7 lol ) 'option' est un champs d'entrée de ma procédure, et NC est un tableau de [2][1] comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int n;
           if(option==0)     n=3;
           if(option==1)     n=StrToInt(NC->Cells[0][0]);
           if(option==2)     n=StrToInt(NC->Cells[0][1]);

    ui le code avec le i++ et le ++i ne change rien ici.

    bref, c'est un peu délicat parce que ma prochaine fonction fait le tri de ces tableaux, donc ça s'embrouille un petit peu.... mais je suis dedans !



    Merci pour toutes vos réponses.

  9. #9
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Question à deux balles, pourquoi n'utilises-tu pas std::vector ?

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Pour le double-pointeur, il y a plus simple: Une allocation par dimension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    float** tab = new float*[7];
    tab[0] = new float[2*7];
     
    for (int i = 1; i < 7; ++i) /* On commence à 1 ici */
        tab[i] = tab[0] + 2*i;
     
     
    // ........................
     
    delete[] tab[0];
    delete[] tab;
    Et on peut en faire une fonction:
    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
    template< class T >
    void Alloc2D(T** &rTab2D, size_t cx, size_t cy)
    {
    	rTab2D = NULL;
     
    	size_t cxy = cx * cy;
    	if(cxy/cx != cy || cxy/cy != cx)
    		throw std::exception("Array dimension overflow");
     
    	//On fait les deux allocations
    	//Si la seconde foire, on libère le premier buffer
    	rTab2D = new T*[cx];
    	try
    	{
    		rTab2D[0] = new T[cxy];
    	}
    	catch(std::bad_alloc const &)
    	{
    		delete[] rTab2D;
    		rTab2D = NULL;
    		throw;
    	}
    	for(size_t x=1 ; x<cx ; ++i)
    		rTab2D[x] = rTab2D[0] + x*cy;
    }
     
    template< class T >
    void Free2D(T** tab2D)
    {
    	if(tab2D != NULL)
    	{
    		delete[] tab2D[0];
    		delete[] tab2D; //Ce delete pourrait être hors du if, mais c'est ss doute plus performant de le mettre ici
    	}
    }
     
    template< class T >
    void Free2D(T** &rTab2D)
    {
    	T** const &rcTab2D = rTab2D; //Pour ne pas s'appeler récursivement
    	Free2D(rcTab2D);
    	rTab2D = NULL;
    }

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

Discussions similaires

  1. Comment creer un tableau dynamique en jsp
    Par juldace dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 04/10/2013, 17h49
  2. creer tableau dynamique
    Par zaynabe dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/11/2007, 17h42
  3. Créer un tableau dynamique des feuilles à imprimer
    Par ouskel'n'or dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 17/08/2007, 10h13
  4. Creer un tableau word dynamiquement en vba
    Par Vince__93700 dans le forum VBA Word
    Réponses: 2
    Dernier message: 08/02/2007, 18h33
  5. [Reflection] Créer un tableau d'objets dynamiquement.
    Par salome dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 25/03/2005, 18h59

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