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 :

Modification de la taille d'un tableau 3D avec realloc


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Par défaut Modification de la taille d'un tableau 3D avec realloc
    Bonjour!

    J'ai un petit problème concernant les tableaux en 3 dimensions dynamiques. Mon but est d'avoir un tableau 3D et d'ensuite modifier sa taille à l'aide d'une fonction. J'ai déjà alloué la mémoire pour mon tableau avec le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	//Création du tableau carte à 3 dimensions  
    	carte = (int ***)malloc(sizeof(int **) * NB_BLOCS_HAUTEUR*2); 	  
    	for (i = 0 ;  i < NB_BLOCS_HAUTEUR*2; i++) 
    	{ 
    	   carte[i] = (int **)malloc(sizeof(int *) * NB_BLOCS_LARGEUR*2); 
     
    	   for (j = 0; j < NB_BLOCS_LARGEUR*2; j++) 
    		  carte[i][j] = (int *)malloc(sizeof(int) * 3); 
    	}
    	if (carte == NULL) //On test si l'allocation a fonctionné
    		exit(0);	//Si non, on quitte
    Je veux ensuite envoyer le tableau carte à une fonction qui en modifie la taille (des 2 premières dimensions, la 3e reste de 3). Je sais comment procéder avec un tableau d'une dimension en utilisant realloc, mais à 3, je bloque. J'imagine que je dois utiliser un code du genre:

    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
     
    changeCarteSize(carte, rows, cols); //Appel de la fonction (correct, j'espère)
     
    int changeCarteSize(int ***carte, int rows, int cols)
    {
    	int i = 0, j = 0, k = 0;
    	//Création du tableau carte à 3 dimensions 
    	carte = (int ***)realloc(carte, sizeof(int **) * rows); 	  
    	for (i = 0 ;  i < rows; i++) 
    	{
    	   carte[i] = (int **)realloc(carte, sizeof(int *) * cols); 
     
    	   for (j = 0; j < cols; j++) 
    		  carte[i][j] = (int *)realloc(carte, sizeof(int) * 3); 
    	}
    	if (carte == NULL) //On test si l'allocation a fonctionné
    		exit(0);	//Si non, on quitte
     
    return 1;
    }
    Ce code ne fonctionne cependant pas. J'imagine que mon utilisation de realloc est mauvaise, surtout que je lui envoie les trois fois le même pointeur carte, alors qu'il me semble que ce ne devrais pas être le cas, mais j'ignore quel pointeur envoyer sinon. Je suis un peu perdu dans tous ces pointeurs de pointeurs de pointeurs... Si vous avez des suggestions de code pour modifier les tailles d'un tableau à 3 dimensions, j'aimerais bien que vous me l'expliquiez.
    Merci d'avance pour votre aide!

  2. #2
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    Bonsoir,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	if (carte == NULL) //On test si l'allocation a fonctionné
    		exit(0);	//Si non, on quitte

    Et si carte[0][0] == NULL ?

    Il faut verifier l'integralité du tableau


    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
     
    changeCarteSize(carte, rows, cols); //Appel de la fonction (correct, j'espère)
     
    int changeCarteSize(int ***carte, int rows, int cols)
    {
    	int i = 0, j = 0, k = 0;
    	//Création du tableau carte à 3 dimensions 
    	carte = (int ***)realloc(carte, sizeof(int **) * rows); 	  
    	for (i = 0 ;  i < rows; i++) 
    	{
    	   carte[i] = (int **)realloc(carte, sizeof(int *) * cols); 
     
    	   for (j = 0; j < cols; j++) 
    		  carte[i][j] = (int *)realloc(carte, sizeof(int) * 3); 
    	}
    	if (carte == NULL) //On test si l'allocation a fonctionné
    		exit(0);	//Si non, on quitte
     
    return 1;
    }
    Ah ? pourquoi ne pas tester le retour de ta fonction ?

    Bref, si tu passe ton tableau comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int changeCarteSize(int ***carte, int rows, int cols)
    Et bien ... tu pourra changer le contenu mais pas le contenant.
    Si tu veux changer la taille du tableau, il faut "rajouter un niveau d'etoile".

    Grosso modo, essaye

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int changeCarteSize(int ***(*carte), int rows, int cols)
    en remplacant tout les

    par


  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Soit N lignes de M colonnes les anciennes dimensions du tableau.
    Tu veux avoir rows lignes et cols colonnes.

    1- Tu réalloues rows lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        carte = realloc(carte, sizeof(int **) * rows);
    2- Les N premières lignes ont déjà M colonnes allouées et il faudra faire un realloc de ces colonnes.
    Les lignes de N à rows - 1 n'ont pas de colonnes allouées et il faudra faire un malloc des colonnes pour ces lignes.
    Le plus simple étant peut-être de mettre à NULL les (nouveaux) pointeurs de N à rows - 1 puis de faire un realloc pour tout le monde.
    Dans tout les cas, cela impose de connaitre N !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       carte[i] = NULL;        (i = N .. rows-1) 
       carte[i] = realloc(carte[i], sizeof(int *) * cols); (i = 0 .. rows-1)
    3- Les lignes 0 à N-1 ont leurs colonnes M à cols - 1 incomplètes : Il faut allouer 3 int
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       carte[i][j] = malloc( sizeof(int) * 3); (i = 0..N-1; j = M..cols-1)
    4- les lignes N à rows - 1 ont toutes leurs colonnes incomplètes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       carte[i][j] = malloc( sizeof(int) * 3); (i = N..rows-1; j = 0..cols-1)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Par défaut
    Merci beaucoup pour vos réponses!

    SofEvans, tu as raison, ma vérification de l'allocation de mémoire était erronée. Je ne suis cependant pas sûr d'avoir compris la partie sur la nécessité de rajouter "un niveau d'étoile". Si j'appelle ma fonction avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    changeCarteSize(carte, rows, cols);
    et que son prototype est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int changeCarteSize(int ***(*carte), int rows, int cols);
    Le compilateur me renvoie une erreur ('int ****' differs in levels of indirection from 'int ***') Si j'envoie &carte à la place de carte lors de mon appel, le programme compile sans erreur. Je ne saisi pas vraiment ce que &carte représente cependant et je suis septique sur cette procédure. Si tu pouvais m'expliquer ce point, ce serait apprécié.

    Diogene, ton algorithme semble très valide, je n'avais pas pensé à ça. Je vais l'essayer et j'en redonne des nouvelles. Merci beaucoup pour cette solution détaillée. Si tu as des idées quant à l'appel de la fonction et son prototype (comme mentionné plus haut), ton avis est également apprécié.

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Cet algo n'est valable que si tu agrandis les dimensions du tableau. Si tu diminues une (ou plusieurs) valeur, il faut prendre des précautions pour éviter des fuites mémoires.

    En ce qui concerne le prototype, la fonction doit fournir la nouvelle adresse du tableau, soit par sa valeur de retour (qui serait alors int***), ou par la liste des paramètres (qui serait alors int ****).
    Dans le premier cas l'appel est de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    carte = changeCarteSize(carte,...)
    et dans le second
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    changeCarteSize(&carte,...)

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Par défaut
    J'ai finalement réussi à écrire ma fonction! Pour l'instant, elle est faite pour agrandir le tableau seulement, je vais bientôt plancher sur le cas ou sa taille diminue. Merci infiniment pour votre aide!

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

Discussions similaires

  1. [Turbo Pascal] Modification de la taille d'un tableau
    Par adrian07 dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 02/02/2009, 19h00
  2. Changer la taille d'un tableau déjà initialisé
    Par totofweb dans le forum C++
    Réponses: 2
    Dernier message: 25/07/2004, 15h55
  3. taille d'un tableau
    Par monstour dans le forum ASP
    Réponses: 3
    Dernier message: 24/06/2004, 15h16
  4. Taille maximum de tableau en Delphi
    Par yannick37 dans le forum Langage
    Réponses: 5
    Dernier message: 03/03/2004, 13h18
  5. qbasic : taille d'un tableau
    Par clood200 dans le forum Basic
    Réponses: 2
    Dernier message: 16/09/2003, 07h26

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