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 :

Fonction qui crée un tableau à 2 dimensions avec pointeur générique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut Fonction qui crée un tableau à 2 dimensions avec pointeur générique
    Bonjours, je souhaite créer une fonction qui permettra de créer un tableau à 2 dimension en ayant un type void en paramètre et qui retournera un pointeur void.

    Le problème c'est que j'ai un message d'erreur : "imcompatible pointeur type, assignement from incompatible pointeur type".
    Je n'arrive pas a trouver la solution pour que mon code marche. Pour un tableau a une dimension sa marche mais pour 2 impossibles.

    voici mon code :

    Dans le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        char **tab=NULL;
     
        tab=alloc_2d(tab,10,10);
    Dans mon .h
    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
     
    void **alloc_2d(void **_ptr,int size1,int size2)
    {
      int i;
      void **ptr=(void**)_ptr;/*cette ligne est pour que le compilo accepte le void pour 1 tableau a
                                     une dimenssion sa marche en enlevant 1 étoile (void *ptr=(void*)_ptr;)*/
     
    assert(size1>0);
    assert(size2>0);
     
      ptr=malloc(size1*sizeof(ptr));
      if(malloc_error(ptr)==NULL)  /*malloc_error est une fonction qui envoi un message d'erreur et qui retourne le pointeur envoyer*/
        {
          free_alloc(ptr); 
          return ptr;
        }
     
      for(i=0;i<size1;i++)
        {
          ptr[i]=malloc(size2*sizeof(ptr[i]));
          if(malloc_error(ptr[i])==NULL)
    	{
    	  for(i=i-1;i>=0;i--)
    	    free_alloc(ptr[i]);
    	  free_alloc(ptr);
    	  return ptr;
    	}
        }
      return ptr;
    }

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Septembre 2013
    Messages
    639
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 639
    Par défaut
    Citation Envoyé par hbx360 Voir le message
    Bonjours, je souhaite créer une fonction qui permettra de créer un tableau à 2 dimension en ayant un type void en paramètre et qui retournera un pointeur void.
    Bonjour. Je ne suis pas sûr de comprendre. Souhaitez-vous créer un tableau (à deux dimensions) de void* ?

    Citation Envoyé par hbx360 Voir le message
    Le problème c'est que j'ai un message d'erreur : "imcompatible pointeur type, assignement from incompatible pointeur type".
    A quelle ligne ?


    Citation Envoyé par hbx360 Voir le message
    Dans mon .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void **alloc_2d(void **_ptr,int size1,int size2)
    {
      int i;
      void **ptr=(void**)_ptr;
    pourquoi caster un void** en void** ?


    Citation Envoyé par hbx360 Voir le message
    ptr=malloc(size1*sizeof(ptr));
    euh... ptr est d'abord un cast de _ptr, et ensuite ptr est immédiatement alloué... à quoi sert donc le paramètre _ptr ?

    Citation Envoyé par hbx360 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      if(malloc_error(ptr)==NULL)  /*malloc_error est une fonction qui envoi un message d'erreur et qui retourne le pointeur envoyer*/
        {
          free_alloc(ptr); 
          return ptr;
        }
    Je ne connais pas ces fonctions malloc_error et free_alloc, mais j'espère que ptr n'est pas alloué deux fois à la suite vu ce qui précède.


    Citation Envoyé par hbx360 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char **tab=NULL;
     
    tab=alloc_2d(tab,10,10);
    lors du retour de l'appel à alloc_2d il y aurait donc un cast implicite de void** vers char**... je ne suis pas sûr que le compilateur doivent laisser passer cela :-)

    Par ailleurs, si vous faites un tableau 2D de void*, alors :

    - void* est le type d'un des éléments stockés dans le tableau ;
    - void** est le type d'une des "lignes" du tableau ;
    - void*** est le type du tableau, qui est alors bien un tableau de 2D de void*.

    Le problème de typage que vous rencontrez viendrait alors de cela.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    • il s'agit plutôt d'un tableau de tableaux que d'un tableau à deux dimensions.
    • ligne 26 du .h, faire plutôt return NULL;
    • le code d'une fonction dans un fichier .h !!! Plutôt utiliser char** alloc2D(int,int); et mettre le code dans un fichier .c
    • à quoi sert le _ptr passé en paramètre? La fonction alloue le bon pointeur, on devrait appeler char** tab = alloc2D(10,10);
    • Pour allouer un tableau la taille de l'élément doit être connue ou passée en paramètre. Dans le corps de la fonction, il faut avoir un char**ptr plutôt qu'un void**ptr, ainsi sizeof(ptr[0]) <=> sizeof(char*) et sizeof(ptr[0][0]) <=> sizeof(char) <=> 1, ou bien veut-on un tableau de tableaux de pointeur?

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut
    Merci pour vos réponses.

    A CodeurPlusPlus :

    Bonjour. Je ne suis pas sûr de comprendre. Souhaitez-vous créer un tableau (à deux dimensions) de void* ?
    En faite je voudrait créer une fonction qui permet de créer un tableau a 2 dimension en passant n'importe quel type, que ce soit un type int, char, double, struct notamment au lieu d'être obliger pour chaque type de faire une fonction.
    Ce que je voudrais c'est éviter ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char **tab_2d(char** tab, int size1, int size2);
    int **tab_2d(int** tab, int size1, int size2);
    double **tab_2d(double** tab, int size1, int size2);
    float **tab_2d(float** tab, int size1, int size2);
    mais plutôt faire une fonction générique qui accepte n'importe quel type et qui retourne un pointeur que je casterait ensuite dans le type que je veux.
    Par exemple faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    char **tab=NULL;
     tab=(char**)alloc_2d(tab,10,10);
     
    /*ma fonction générique qui crée un tableau 2d et qui retourne un void** */
    le prototype serai donc void** alloc_2d(void** tab, size1, size2);
    Comme ça je n'aurai plus qu'une fonction pour créer n'importe quel type de tableau 2d au lieu d'en avoir une pour chaque type.

    pourquoi caster un void** en void** ?
    C'était pour éviter que le compilateur me mette un message d'erreur.
    J'ai fait une fonction générique qui crée un tableau a une dimension et j'ai fait comme cela pour évité une erreur de ce style incompatible type pointer.

    euh... ptr est d'abord un cast de _ptr, et ensuite ptr est immédiatement alloué... à quoi sert donc le paramètre _ptr ?
    idem que en haut pour éviter que le compilo rale sa marche pour le tableau à une dimension mais pas pour le 2.

    Mon tableau à une dimension celui-ci marche:

    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
     
    void *alloc(void *_ptr,int size)
    {
      void *ptr=(void*)_ptr;
     
      assert(size>0);
     
      ptr=malloc(size*sizeof(ptr));
      if(malloc_error(ptr)==NULL)
        {
          free_alloc(ptr);
          return ptr;
        }
      return ptr;
    }


    Je ne connais pas ces fonctions malloc_error et free_alloc, mais j'espère que ptr n'est pas alloué deux fois à la suite vu ce qui précède.
    Non malloc_error est une fonction que j'ai créé moi; elle met juste un message d'erreur et renvoi le pointeur
    Voici le code de malloc_error:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void *malloc_error(void *ptr)
    {
      if(ptr==NULL)
        tools_strerror("The allocation failed, the block(s) was released : %s");
     
      return ptr;
    }
    Pour free_alloc c'est aussi une fonction que j'ai fait moi et qui libère la mémoire.
    Voici son code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void free_alloc(void *_ptr)
    {
      void *ptr = (void*) _ptr;
      free(ptr);
      ptr=NULL;
    }

    - void* est le type d'un des éléments stockés dans le tableau ;
    - void** est le type d'une des "lignes" du tableau ;
    - void*** est le type du tableau, qui est alors bien un tableau de 2D de void*.
    Merci pour cette info.
    Merci pour ton aide.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut
    A dalfab

    [*] le code d'une fonction dans un fichier .h !!! Plutôt utiliser char** alloc2D(int,int); et mettre le code dans un fichier .c
    Oui je me suis trompé c'est un .c et non un .h

    à quoi sert le _ptr passé en paramètre? La fonction alloue le bon pointeur, on devrait appeler char** tab = alloc2D(10,10);
    C'était pour évité que le compilo rale.

    Pour allouer un tableau la taille de l'élément doit être connue ou passée en paramètre. Dans le corps de la fonction, il faut avoir un char**ptr plutôt qu'un void**ptr, ainsi sizeof(ptr[0]) <=> sizeof(char*) et sizeof(ptr[0][0]) <=> sizeof(char) <=> 1, ou bien veut-on un tableau de tableaux de pointeur?
    J'ai essayé cette méthode mais le problème c'est que si je veux un tableau 2D de int cela ne marche pas.

    Merci pour ton aide.

  6. #6
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Il existe ici un malentendu sur le fonctionnement de l'opérateur sizeof.

    Le résultat de sizeof(foo) est évalué à la compilation, il ne s'agit pas de RTTI ! Tu écris : ptr=malloc(size*sizeof(ptr));, es-tu bien conscient que c'est équivalent à sizeof(<type de ptr, soit ici void *>) ?

    Ce n'est pas un hasard si malloc & co. demandent un paramètre de type size_t : c'est la seule façon de connaître la taille du bloc à allouer. Bases-toi plutôt sur les signatures de fonction de la bibliothèque standard.


    Evites aussi de faire taire le compilo avec un cast, gcc est réputé plutôt verbeux mais la plupart du temps il râle tout de même pour de bonnes raisons.

Discussions similaires

  1. Réponses: 12
    Dernier message: 05/06/2007, 07h36
  2. Réponses: 11
    Dernier message: 14/10/2006, 21h26
  3. [VB] Fonction qui retourne un tableau
    Par ptitsoleil87 dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 24/12/2005, 10h52
  4. Fonction qui renvoie un tableau?
    Par elm dans le forum C
    Réponses: 23
    Dernier message: 21/12/2005, 12h44
  5. Fonction qui retourne un tableau
    Par _lara_ dans le forum ASP
    Réponses: 6
    Dernier message: 24/05/2004, 15h06

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