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 :

Probleme allocation tableau multidimensions


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut Probleme allocation tableau multidimensions
    Bonjour j'ai un soucis avec mon allocation, cela ne fonctionne pas.

    J'ai crée un .C pour allouer un tableaux a deux dimensions mais de caracteres
    Voila la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* sa déclaration */
    #ifndef ALLOCATION
     #define ALLOCATION
     
    	char VALEO_Allocation(char **matrice, int NL, int NC);
     
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* le coude source */
    char VALEO_Allocation(char ***matrice, int NL, int NC)
    {
    	int i;
     
    	*matrice = ((char**)malloc(NL*sizeof(char*)));
     
    	for(i=0; i<NL; i++)
    		*matrice[i]= ((char*)malloc(100*NC*sizeof(char)));
     
    	return(*matrice);
    }
    et mon main.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char **tab[100]==NULL; /* je sais pas si le NULL est bien nécessaire ici*/
    /* entre je fai une lecture de mon fichier pour connaitre le nb de ligne et de colonne exact du tableau */
    VALEO_Allocation(&tab, nb_ligne, nb_colonne);
    Je rentre mon tableau en parametre de la fonction avec * car il va etre modifié a l'interieur de "VALEO_Allocation(&tab, nb_ligne, nb_colonne);"
    Je fais un free du pointeur a la fin de mon main.

    Voila les warning que VC++ me sort :
    - warning C4028: formal parameter 1 different from declaration
    - char' differs in levels of indirection from 'char **'

    il me semble qu'en cours j'avais fait la meme chose pour un tableau a deux dimensions mais pour entiers et ca marchait.

  2. #2
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Je ne sais pas si tu utilises beaucoup le copié collé mais il a une incohérence entre d'un côté le prototype de la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char VALEO_Allocation(char **matrice, int NL, int NC);
    et d'un autre son implémentation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char VALEO_Allocation(char ***matrice, int NL, int NC)
    Une indirection de trop...


    Ca ne peut pas retourner un char ceci.

    Tu as regardez la faq en ce qui concerne les allocations ?

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    En faite je veu passer le tableau en parametre c'est pour ca que j'ai rajouté une etoile.
    Mais je ne me rappel plus si on doit l'ajouter dans le prototype.

    Pour le return pour un char je ne sais pas comment on doit faire. J'avais fait ca mais pour un tableau d'entiers c'est vrai.

  4. #4
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Citation Envoyé par orj30754
    Mais je ne me rappel plus si on doit l'ajouter dans le prototype.
    oui.

    En C++ le compilateur traitera les 2 comme 2 fonctions différentes(liés a la surcharge)


    Tu as regardé dans la faq ?

  5. #5
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    J y suis allé mais je n'ai trouvé que le passage d'un paramatre int*.
    Sinon l'allocation doit marcher, en tout cas elle fonctionnait pour un tableau a deux dimensions d'entier.

    Sinon je vais regarder s'il y a un truc sur le return pour un char.

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Bon voila ce que j'ai fais, ca me parait bizarre mais bon j'ai plus d'erreurs par contre ca plante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char VALEO_Allocation(char ***matrice, int NL, int NC)
    {
    	int i;
     
    	*matrice = ((char**)malloc(NL*sizeof(char*)));
     
    	for(i=0; i<NL; i++)
    		*matrice[i]= ((char*)malloc(100*NC*sizeof(char)));
     
    	return(***matrice);
    }
    Quand je debeug la premiere allocation du NL se fait bien, seulement lors du 2eme passage ds la boucle ca plante.
    Ca me met sur une fenetre d'erreur

    Exception non gérée à 0x00411508 dans Projet MATRICE.exe*: 0xC0000005: Violation d'accès lors de l'écriture à l'emplacement 0xcccccccc.

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il y a quelques incohérences au niveau de ce que tu écris...

    Déjà, si tu veux renvoyer une matrice de caractères, c'est un tableau de pointeurs que tu dois renvoyer... donc, un "pointeur de pointeur" de type char...

    Ensuite, il est difficile de gérer les "pointeurs de pointeurs de pointeurs", et, à bien y réfléchir, c'est purement inutile dans ce cas...

    En effet, il pourrait très bien te suffire d'utiliser un code du genre de
    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
     
    /* fonction qui renvoie une matrice de caractères
       @in nombre de lignes
           nombre de colones
       @out la matrice allouée
     */
    char ** VALEO_Allocation(int ligne, int colone)
    {
        char** matrice;
        int i;
        if((matrice=malloc(sizeof(char*)*ligne))!=NULL)
        {
         /* l'allocation a réussi */
            for(i=0;i<colone;i++)
            {
                if((matrice[i]=malloc(sizeof(char)*colone)==NULL)
                {
                     /* problème lors de l'allocation d'une colone de caractères */
                     /* libération de la mémoire déjà allouée pour la matrice */
                     for(int j=0;j<i;j++)
                     {
                          free(matrice[j]);
                     }
                     free(matrice);
                     printf("echec lors de l'allocation... on quitte desole\n");
                     /* renvoie null pour quitter les boucles */
                     return NULL;
                }
            }
        }
        else
        {
            /* on n'a meme pas pu allouer l'espace pour notre tableau de 
               pointeurs */
            printf("echec lors de l'allocation... on quitte desole\n");
        }
        return matrice;/* vaudra NULL s'il y a eu échec lors de l'allocation de
                          mémoire */
    }
    qui serait utilisé sous la forme de
    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
     
    int main(int argc, char *argv[])
    {
        /* déclaration de notre matrice de réception */
        char** matrice=NULL;
        /* et des nombres de lignes et de colones */
        int ligne=10;
        int colone=20;
        /* appel de la fonction pour l'initialiser */
        matrice=VALEO_Allocation(ligne,colone);
        /*vérification de la réussite de l'allcocation */
        if(matrice==NULL)
        {
            return EXIT_FAILURE;
        }
        /* arrivé à ce point, on a bel et bien notre matrice disponible */
        ...
        /* N'oublions quand meme pas de libérer la mémoire allouée à la matrice */
        for(int i=0;i<ligne;i++)
            free(matrice[i]);
        free(matrice);
        /* et sortie sur réussite */
        return EXIT_SUCCESS;
    }
    Retiens toujours le fait qu'il est beaucoup plus facile de se passer des pointeurs (de pointeurs), si c'est possible, que de commencer à "jouer" avec...

    Et c'est particulièrement vrai s'il s'agit de commencer à essayer d'utiliser des pointeurs de pointeurs de pointeurs [de...] ...

    Si tu as le choix, préfères toujours limiter l'utilisation de pointeurs pour passer des argument à ce qui est réellement nécessiare, quitte à récupérer l'élément modifié par retour de fonction...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Je sais pas si
    et
    veulent dire la meme chose.
    Je dois avoir un tableau de caractere a 2 dim dont chaque case peut contenir un mot de 100 lettres max.
    pour moi c'est un tableau d'une seule dim pouvant contenir des mots de tailles a définir.

    A part ca ton allocation ma l'air pas mal et propre. Une fois le pb du char reglé j'essayerai pour voir si ca tourne

  9. #9
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Bon voila j"ai tester le code et il ne marche pas.
    Voila l'erreur :
    Exception non gérée à 0x102aece9 dans Projet MATRICE.exe*: 0xC0000005: Violation d'accès lors de l'écriture à l'emplacement 0xffffffcd
    Et voila ce que j'ai fait :
    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
    /* MAIN.C */
    tab=VALEO_Allocation(nb_ligne, nb_colonne);
     
    	if(tab==NULL){
    		for(i=0; i<nb_ligne; i++)
    			free(tab[i]);
    		free(tab);
    	}
    	else{
    		for(i=0; i<nb_ligne; i++)
    			for(j=0; j<nb_colonne; j++)
    				strcpy(tab[i][j], "ca marche");
    		for(i=0; i<nb_ligne; i++)
    			for(j=0; j<nb_colonne; j++)
    				printf("%s\n", tab[i][j]);
    	}
    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
    /* ALLOCATION.C */
    char** VALEO_Allocation(int NL, int NC)
    {
    	int i, j;
    	char **matrice;
     
    	if((matrice = ((char**)malloc(NL*sizeof(char*)))) != NULL){
    		for(i=0; i<NL; i++)
    			if((matrice[i]= ((char*)malloc(100*NC*sizeof(char)))) == NULL)
    			{
    				for(j=0; j<i; j++)
                     {
                          free(matrice[j]);
                     }
    				free(matrice);
    				printf("echec lors de l'allocation... on quitte desole\n");
    				return NULL;
    			}
    	}
     
    	else
            printf("echec lors de l'allocation... on quitte desole\n");
     
        return matrice;
    }

  10. #10
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Bon j'ai un soucis avec mon code ca ne marche pas.
    Quand je le test en debeug, au moment du 2 eme tour ds la boucle pour allouer *matrice[i] ca plante

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    fait attention au fait que la libération que tu trouves dans main sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	if(tab==NULL){
    		for(i=0; i<nb_ligne; i++)
    			free(tab[i]);
    		free(tab);
    	}
    est non seulement inutile mais dangereuse

    S'il faut bien quitter l'application parce que l'allocation n'a pas réussi, l'ensemble de la libération a été effectué correctement au sein meme de la fonction...

    Si tab vaut NULL, tout ce qu'il reste à faire ici, c'est ... sortir sur un échec...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Merci mais le soucis n'est pas la mais plutot dans la fonction VALEO_Allocation....

    ken je fais mon malloc avec le nb_colonne(NC). AU moment du 2 eme passage et bein PAN ca pete.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void VALEO_Allocation(char*** matrice, int NL, int NC)
    {
    	int i;
     
    	if((*matrice = (char**)malloc(NL*sizeof(char*))) != NULL){
    		for(i=0; i<NL; i++)
    			if((*matrice[i]=(char*)malloc(NC*sizeof(char))) == NULL)
    				printf("echec lors de l'allocation...\n");
    	}
     
    	else
            printf("echec lors de l'allocation...\n");
    }

  13. #13
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Tu peux peut être trouver quelque chose pour éviter d'avoir à utiliser des variables de pointeur sur pointeur de pointeur parce que da aide pas a la lisibilité et en plus c'est pas plus aisé pour trouver les bugs.

    Je dis ça mais je dis rien.

  14. #14
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Oui je suis d'accord et je me doute qu'il existe des choses meilleurs.
    C'est ca la question..... Mais quoi????

  15. #15
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par orj30754
    Oui je suis d'accord et je me doute qu'il existe des choses meilleurs.
    C'est ca la question..... Mais quoi????
    Retourner le pointeur de pointeur (c'est plus dans la logique objet) :
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    char **VALEO_Allocation (int NL, int NC)
    {
      char **matrice = NULL;
     
      matrice = malloc (NL * sizeof (*matrice));
      if (matrice != NULL)
      {
        int i;
     
        for (i = 0; i < NL; i++)
        {
          matrice[i] = malloc (NC * sizeof(**matrice));
          if (matrice[i] == NULL)
          {
            int j;
     
            for (j = 0; j < i; j++)
            {
              free (matrice[i]), matrice[i] = NULL;
            }
            free (matrice), matrice = NULL;
            printf("echec lors de l'allocation...\n");
          }
        }
      }
      else
      {
        printf("echec lors de l'allocation...\n");
      }
      return matrice;
    }

  16. #16
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Merci gégé nikel ca marche...

Discussions similaires

  1. [CR8.5] Probleme de tableau
    Par Sto59 dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 21/02/2007, 15h07
  2. [FLASH 8] Problème tableau multidimension
    Par julien.63 dans le forum Flash
    Réponses: 8
    Dernier message: 01/12/2006, 17h29
  3. jolie probleme de tableau
    Par racoon971 dans le forum C++
    Réponses: 2
    Dernier message: 04/03/2005, 11h31
  4. probleme de tableau dynamique
    Par El Krotal dans le forum C
    Réponses: 9
    Dernier message: 25/06/2004, 17h00
  5. [C#] Probleme de tableau
    Par djsbens dans le forum Windows Forms
    Réponses: 8
    Dernier message: 08/06/2004, 14h04

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