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 :

passage de tableau dynamique


Sujet :

C

  1. #1
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut passage de tableau dynamique
    salut,
    j'ai écrit un bout de script simplifié au maximum pour comprendre pourquoi je n'arrive pas à passer un tableau de caractère dans une fonction.
    voici mon code :
    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
    #include "libecoPCR/ecoPCR.h"
    #include <stdio.h>
    #include <string.h>
    #include <getopt.h>
     
    void printpattern(char *pattern, int p){
    	int i;
    	for(i=0;i<p;i++){
    		printf("%s\n",pattern[i]); // warning: format '%s' expects type 'char *', but argument 2 has type 'int'
    	}
    }
     
    int main(int argc, char **argv){
     
    	char 	**pattern	= MALLOC(sizeof(char *),"error pattern initialisation");
    	int 	p			=0;
     
    	for (p=0 ; argc > optind ; optind++, p++){
    		pattern[p] = MALLOC(strlen(argv[optind])+1,
    								"Error on pattern allocation");
    		pattern[p] = argv[optind];
    	}
     
    	printpattern(*pattern,p); 
     
    	return 0;
     
    }
    Mon compilateur me met un warning et j'ai un bus error à l'execution. J'ai essayé différentes solutions, mais je n'arrive pas à récupérer le contenu de mon tableau pattern.
    Merci du coup de main

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Salut !


    Tu veux passer un pointeur de pointeur sur un argument qui n'est qu'un simple pointeur... normal, change l'argument de ta fonction au moins en pointeur de pointeur sur char !

    L'appel n'est pas bon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printpattern(*pattern,p);
    Fait plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printpattern(pattern,p);

  3. #3
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    ok, ça marche.
    merci beaucoup, je commençais à chauffer sérieusement

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par julien.63
    salut,
    j'ai écrit un bout de script....
    ATTENTION à l'usage des mots.. Tu es en informatique, chaque mot a un sens...

    Ce n'est pas un script, mais un programme, que tu as écrit..

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par julien.63
    ok, ça marche.
    merci beaucoup, je commençais à chauffer sérieusement
    Bin faut juste rester logique c'est tout. Tu utilises un pointeur de pointeur alors il est normal que ton argument de la fonction soit au moins du même type !

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par julien.63
    salut,
    j'ai écrit un bout de script simplifié au maximum pour comprendre pourquoi je n'arrive pas à passer un tableau de caractère dans une fonction.
    voici mon code :
    <...>Mon compilateur me met un warning et j'ai un bus error à l'execution. J'ai essayé différentes solutions, mais je n'arrive pas à récupérer le contenu de mon tableau pattern.
    Bah, il faut être simple, logique et cohérent :
    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
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    void printpattern (char **pattern, int p)
    {
       int i;
       for (i = 0; i < p; i++)
       {
          printf ("%s\n", pattern[i]);
       }
    }
     
    int main (int argc, char **argv)
    {
       char **pattern = malloc (sizeof *pattern * (argc - 1));
       if (pattern != NULL)
       {
          int r = 1;
          int w = 0;
          while (r < argc)
          {
             pattern[w] = strdup (argv[r]); /* POSIX.1 */
             r++;
             w++;
          }
          printpattern (pattern, w);
          free (pattern);
       }
       return 0;
    }
    Pose des questions si tu ne comprends pas (et adapte ce code à getopt())

    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    * monappli -s10 -d -a12 -c15
    ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    -s10
    -d
    -a12
    -c15
     
    Press ENTER to continue.

  7. #7
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    voici une version avec getopt
    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
    #include <stdio.h>
    #include <string.h>
    #include <getopt.h>
    #include <stdlib.h>
     
    void printpattern(char **pattern, int p){
    	int i;
    	for(i=0;i<p;i++){
    		printf("%s\n",pattern[i]);
    	}
    }
     
    int main(int argc, char **argv){
     
    	char 	**pattern	= malloc(sizeof *pattern * (argc -1));
    	int 	p			= 0;
     
    	while (getopt(argc, argv, "a:b:c:") != -1) {
     	   pattern[p] = strdup(optarg);
    	   p++;
    	}
     
    	printpattern(pattern,p);
    	free(pattern);
     
    	return 0;
     
    }
    donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SANCY:~/Documents/c $ ./ecotest -asdf -boii -cppe
    # sdf
    # oii
    # ppe

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par julien.63
    voici une version avec getopt
    Attention à libérer ce qui a été alloué avec strdup() :
    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
     
    #include <stdio.h>
    #include <string.h>
    #include <getopt.h>
    #include <stdlib.h>
     
    void printpattern (char **pattern, int p)
    {
       int i;
       for (i = 0; i < p; i++)
       {
          printf ("%s\n", pattern[i]);
       }
    }
     
    int main (int argc, char **argv)
    {
       char **pattern = malloc (sizeof *pattern * (argc - 1));
       int p = 0;
       while (getopt (argc, argv, "a:b:c:") != -1)
       {
          pattern[p] = strdup (optarg);
          p++;
       }
       printpattern (pattern, p);
     
       {
          int i;
          for (i = 0; i < p; i++)
          {
             free (pattern[i]);
          }
       }
       free (pattern);
       return 0;
    }

  9. #9
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    Est qu'on pourrait imaginer une fonction pour libérer la 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <stdio.h>
    #include <string.h>
    #include <getopt.h>
    #include <stdlib.h>
     
    void freememory(char **tab, int num){
    	int i;
    	for (i=0;i<=num;i++)
            {
    		free(tab[i]);	
    	}
    	free(tab);
    }
     
    void printpattern (char **pattern, int p)
    {
       int i;
       for (i = 0; i < p; i++)
       {
          printf ("%s\n", pattern[i]);
       }
    }
     
    int main (int argc, char **argv)
    {
       char **pattern = malloc (sizeof *pattern * (argc - 1));
       int p = 0;
       while (getopt (argc, argv, "a:b:c:") != -1)
       {
          pattern[p] = strdup (optarg);
          p++;
       }
       printpattern (pattern, p);
       freememory (pattern, p);
       return 0;
    }

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par julien.63
    Est qu'on pourrait imaginer une fonction pour libérer la mémoire?
    Absolument. La prochaine étape, la structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct tab_string
    {
       char **tab;
       int num;
    };
    la suivante, l'ADT (TAD) :

    http://emmanuel-delahaye.developpez.com/tad.htm

  11. #11
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    en utilisant une structure.
    Je ne sais pas si les malloc sont bien faits?
    D'autres part j'ai un souci sur le free(&tab->num); dans la fonction freememory. Ca compile bien mais j'ai une erreur à l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    malloc: ***  Deallocation of a pointer not malloced: 0x3; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug
    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
    44
    45
    #include <stdio.h>
    #include <string.h>
    #include <getopt.h>
    #include <stdlib.h>
     
    typedef struct {
    	char 	**tab;
    	int 	num;
    } tab_string;
     
    void freememory(tab_string *tab)
    {
    	int i;
    	for (i=0;i<=tab->num;i++)
        {
    		free(tab->tab[i]);	
    	}
    	free(&tab->num);
    	free(tab);
    }
     
    void printpattern (tab_string *tab)
    {
       int i;
       for (i = 0; i < tab->num; i++)
       {
          printf ("%s\n", tab->tab[i]);
       }
    }
     
    int main (int argc, char **argv)
    {
       tab_string	*tab = malloc( (sizeof(char) * (argc-1)) + 1);
       tab->num = 0;
       tab->tab = malloc(sizeof(char)*(argc-1));
     
       while (getopt (argc, argv, "a:b:c:") != -1)
       {
          tab->tab[tab->num] = strdup (optarg);
          tab->num++;
       }
       printpattern (tab);
       freememory (tab);
       return 0;
    }

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    normal ..

    tab.num est un ENTIER, pas un pointeur..

    Quand tu libères tab il libère automatiquement la place de l'entier, pusiqu'il est DANS la structure.

    Les free ne doivent correspondre qu'aux malloc/calloc correspondants..

  13. #13
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    Quand tu libères tab il libère automatiquement la place de l'entier, pusiqu'il est DANS la structure.
    ok peut être que je commence à comprendre.
    Il libère num parce qu'il est DANS la structure donc, mais il faut libérer les tab->tab[i] car ils sont en dehors, la structure ne contenant que l'adresse de ces chaines qui sont elles mêmes libérées en même temps que num?

  14. #14
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    absolument..

    C'est pour ça qu'il faut libérer les tab->tab[i] AVANT de libérer tab, sinon tu ne sauras plus où c'est et tu ne pourras plus atteindre cette zone..

  15. #15
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    un grand merci à tous et spécialement à Emmanuel
    je vais imprimer ce post et le lirai tous les matins

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 23/03/2007, 09h40
  2. Réponses: 4
    Dernier message: 01/01/2007, 10h26
  3. Réponses: 4
    Dernier message: 19/12/2006, 20h06
  4. passage par paramètre d'un tableau dynamique bidimensionnel
    Par shaftJackson dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 17/07/2006, 13h28
  5. Passage de tableau dynamique en paramètre
    Par Didier L dans le forum Langage
    Réponses: 3
    Dernier message: 08/09/2005, 23h04

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