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 :

strdup et tableau a double dimension


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 123
    Points : 85
    Points
    85
    Par défaut strdup et tableau a double dimension
    Bonjour.
    Je dois coder une fonction qui renvoie un tableau de caractères a double dimensions contenant:
    -pour les premières cases des pointeur sur des chaînes de caractères copiées grâce à la fonction strdup
    -pour la dernière case la valeur NULL

    Je bute sur deux problèmes:
    -mon l' initialisation de mon tableau de chaîne de caractères semble marcher mais au bout d un moment la chaine stockée dans la première case change
    -comment libérer mon tableau crée

    La macro SRV_N_UTIL_PTR(srv) me retourne le nombre nécessaire de case du tableau

    La macro SRV_UTIL_NAME(srv,compteur) me retourne une chaîne de caractère

    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    char **get_liste_utilisateurs(void)
    {
    	char** stockage;
    	int compteur;
    	int nombreCaseTableau=*SRV_N_UTIL_PTR(srv); 
    // SRV_N_UTIL_PTR(srv) = Une macro qui me retourne le nombre nécessaire de case du tableau +1
     
    	stockage=malloc(nombreCaseTableau*sizeof(char));
    	//creation d un tableau de la taille du nombre d enregistre
    	if(stockage==NULL)
    	{
    		perror("\n impossible d allouer la RAM necessaire a la list d users \n");
    		exit(EXIT_FAILURE);
    	}
     
    	printf("\n nbre de case du tableau de stockage  %i \n",nombreCaseTableau);
     
    	compteur=0;
    	while(compteur<=nombreCaseTableau-1)
    	{
    		// recuperation des données : utiliser strdup()
    		stockage[compteur]=strdup(SRV_UTIL_NAME(srv,compteur));
    		printf("\ntableau de stockage: %i %s \n",compteur,stockage[compteur]);
    		compteur++;
    		printf("\n str %s \n", stockage[0]);
    	}
    	// Marquer la fin du tableau
    	stockage[nombreCaseTableau]=NULL;
     
     
    	printf("\ntableau de stockage: %i %s \n",compteur,stockage[nombreCaseTableau]);
     
    	return	stockage;
    }
     
    int main(int argc, char **argv)
    {
    	char** listeUsers;
     
    	listeUsers=get_liste_utilisateurs();
     
    	int cpt=0;
     
    	printf("\n liste des users un test: %s \n", listeUsers[0]);
     
    	while(listeUsers[cpt]!=NULL)
    	{
    		printf("\n liste des users: %i %s \n", cpt, listeUsers[cpt]);*
    		//free(listeUsers[cpt]);
    		cpt++;
    	}
    	//free(listeUsers);
     
    	return 0;
    }
    Voila le code qui s affiche dans la console avec les appelles à la fonction free commentés.

    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
    ===============retourne liste user===============
     nbre de case du tableau de stockage 5 
    tableau de stockage: 0 aaaaaaaa 
     str aaaaaaaa 
    tableau de stockage: 1 bbbbbb 
     str aaaaaaaa 
    tableau de stockage: 2 cccccc 
     str aaaaaaaa 
    tableau de stockage: 3 dddddddddddd 
     str aaaaaaaa 
    tableau de stockage: 4 eeeee 
     str `�aaaa 
    tableau de stockage: 5 (null) 
     liste des users un test: `� 
     liste des users: 0 `� 
     liste des users: 1 bbbbbb 
     liste des users: 2 cccccc 
     liste des users: 3 dddddddddddd 
     liste des users: 4 eeeee
    Comme vous pouvez le voir lors de ma quatrième initialisation la chaine pointée dans la première case du tableau se trouve corrompue.
    Et je n'ai aucune idée du pourquoi???

    Si j'utilise free pour
    libérer toute les chaînes contenues dans mon tableau
    libérer mon tableau lui même j ai le droit à un core dumped

    Merci d'avance de votre aide

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    Je viens de m'apercevoir que j ai le problème des que je met dans le tableau a la case 4:

    Dans le code suivant il suffit que:

    j'initialise la case 0 avec une chaîne "aaaaaaaa"
    j'initialise la case 4 avec une chaîne "dddddddddddd"

    Pour que ca bug.

    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
    char **get_liste_utilisateurs(void)
    {
    	char** stockage;
    	int compteur;
     
    	stockage=malloc(4*sizeof(char));
    	//creation d un tableau de la taille du nombre d enregistre +1
    	if(stockage==NULL)
    	{
    		perror("\n impossible d allouer la RAM necessaire a la list d users \n");
    		exit(EXIT_FAILURE);
    	}
     
    	printf("\n nbre de case du tableau de stockage (comprend 0) %i \n",nombreCaseTableau);
     
    	compteur=0;
     
    		stockage[0]=strdup(SRV_UTIL_NAME(srv,0));
    		printf("\ntableau de stockage: %i %s \n",compteur,stockage[0]);
    		printf("\n str %s \n", stockage[0]);
     
    		stockage[4]=strdup(SRV_UTIL_NAME(srv,4));
    		printf("\ntableau de stockage: %i %s \n",compteur,stockage[4]);
    		printf("\n str %s \n", stockage[0]);
     
     
    	// Marquer la fin du tableau
    	stockage[4]=NULL;
     
     
    	printf("\ntableau de stockage: %i %s \n",compteur,stockage[nombreCaseTableau]);
     
    }
    En utilisant gdb je me suis apercus que

    avant l'execution de la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    stockage[4]=strdup(aaaaaaaa);
    Il n'y a pas de bug
    C'est seulement apres que les ennuis commencent

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [(gdb) print stockage[0]
    $7 = 0x804a018 "(�\004\baaaa"
    Si quelqu'un voit le problème, à une solution, à des conseils je suis tout ouie

  3. #3
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    si seulement il n'y en avait qu'un, problème.....

    Tu confonds pointeurs, pointeurs de pointeurs, char, char *, indice, nombre...

    Alors prenons dans l'ordre :

    1. Tu déclares :

      mais ensuite tu fais :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
       
      	stockage=malloc(4*sizeof(char));
      ya pas quelque chose qui te choque là-dedans ????

      tu déclares un char **, et tu alloues des char....


      char ** devrait pouvoir stocker l'adresse retournée de l'allocation dynamique de .......

      un tableau de char *.

      Donc il faudrait déjà faire :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
       
      	char** stockage=NULL;
       
      	stockage=malloc(4*sizeof(char*));
    2. Tu fais :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
       
      	while(compteur<=nombreCaseTableau-1)
      C'est pas plus simple de faire :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      	while(compteur < nombreCaseTableau)
      ??

    3. Ta chaine est toujours la même car strdup retourne un char *, que tu stockais dans un char (voir problème d'allocation en 1). Donc ...

    4. Tu écris :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      	stockage[nombreCaseTableau]=NULL;
      à ton avis combien vaut nombrecaseTableau ??

      4, on est bien d'accord ??

      Tu as alloué combien d'emplacements ??


      4, on est toujours d'accord ??
      (remplis en partant de 0 à < 4, c'est-à-dire 3)


      Où est-ce que tu as vu qu'il y avait de la place pour tableau[4], qui, rappelons-le, est le 5ième élément... ?????
      Si tu veux construire ta liste comme ça, il te faut allouer 1 élément de plus que le nombre d'éléments que tu souhaites...


    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    Ok grâce à toi j'ai résolu les problèmes rencontrés.
    Je devrais relire mes cours en C :p

    Un ptite dernière question: Est-ce que le code suivant (qui compile) me permet bien de libérer le tableau retourne par get_liste_utilisateurs?

    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
     
     
    int main(int argc, char **argv)
    {
     
    listeUsers=get_liste_utilisateurs();
     
    	int cpt=0;
    	while(listeUsers[cpt]!=NULL)
    	{
    		free(listeUsers[cpt]);
    		cpt++;
    	}
    }
    	free(listeUsers);
    Merci de tes réponses

  5. #5
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    oui
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    oui
    Ok mes qeustions sont résolues

    Merci à tous

  7. #7
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    n'oublie pas le flag
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

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

Discussions similaires

  1. Tableau à double dimension
    Par 0635425 dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 25/02/2008, 09h46
  2. Mettre un tableau à double dimension en session
    Par The Molo dans le forum ASP
    Réponses: 4
    Dernier message: 20/02/2008, 14h54
  3. Afficher un tableau à double dimension
    Par The Molo dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 20/02/2008, 12h37
  4. Réponses: 6
    Dernier message: 15/12/2006, 19h29
  5. [FLASH MX] Tableau à double dimension
    Par totoche dans le forum Flash
    Réponses: 4
    Dernier message: 11/10/2005, 22h04

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