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 glibc avec chaine de caracteres.


Sujet :

C

  1. #1
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut probleme glibc avec chaine de caracteres.
    bonsoir,

    Je me suis fait un code qui permet de concatener des chaine de caracteres.

    Voici le 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
    29
    30
    31
    32
    char *str_concat(char *cs, ...) {
    	va_list va;
    	const char *ct;
    	char *s;
    	size_t size;
     
    	size = 1;
    	s = NULL;
     
    	va_start(va, cs);
    	while ((ct = va_arg(va, char *)) != NULL) 
    		size += strlen(ct);
     
    	s = (char *) calloc(size * sizeof(char), sizeof(char));
     
    	if (s == NULL)
    	{
    		printf("in str_concat : malloc() failed.\n");
    		fflush(stdout);
    	}
     
    	else
    	{
    		va_start(va, cs); 	
    		strcpy(s, cs);
     
    		while ((ct = va_arg(va, char *)) != NULL) 
    			strcat(s, ct);
    	}
     
    	return s;
    }

    lorsque je l utilise je fais par exemple :
    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
     
    void init_dir(char *rep_dir_path, list_t l) 
    {
    	int path_len;
    	char *path;
     
    	path_len = strlen(rep_dir_path);
     
    	mkdir(rep_dir_path, S_IRWXU);
     
    	path = str_concat(rep_dir_path, "/Divers", NULL);
    	mkdir(path, S_IRWXU);
     
    	while (fdt_list != NULL) 
    	{
    		path = str_concat(rep_dir_path, "/", l->name, NULL);
    		mkdir(path, S_IRWXU);
    		l = l->next;
    		free(path);
    	}
     
    }
    list_t est une liste de chaine de caracteres.

    Ca me fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x08053298 ***
    Aborted
    Je ne comprend pas pourquoi .... Meme sans le free cela me fait une erreure qui est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** malloc(): memory corruption: 0x08052cc8 ***
    Aborted

    Merci

  2. #2
    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 Mr_Chut
    Je me suis fait un code qui permet de concatener des chaine de caracteres.

    Ca me fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x08053298 ***
    Aborted
    <...>
    Ceci fonctionne :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <string.h>
     
    static char *str_concat (char *cs,...)
    {
       char *s = NULL;
       size_t size = 1;
       {
          const char *ct;
          va_list va;
          va_start (va, cs);
          while ((ct = va_arg (va, char *)) != NULL)
          {
             size += strlen (ct);
          }
          va_end (va);
       }
       printf ("size = %lu\n", (unsigned long) size);
       s = malloc (size);
     
       if (s == NULL)
       {
          printf ("in str_concat : malloc() failed.\n");
       }
       else
       {
          const char *ct;
          va_list va;
          va_start (va, cs);
          strcpy (s, cs);
     
          while ((ct = va_arg (va, char *)) != NULL)
          {
             strcat (s, ct);
          }
          va_end (va);
       }
       return s;
    }
     
    int main ()
    {
       char *s = str_concat ("a", "bc", "def", NULL);
     
       if (s != NULL)
       {
          printf ("'%s'\n", s);
          free (s), s = NULL;
       }
     
       return 0;
    }

  3. #3
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    merci je vais essayer.

    Tu pourrais me dire l utilisation de static pour une fonction, car je l utilise jamais, et je ai que trouver une explication pour son utilisation avec une variable.

    Merci.

  4. #4
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    ok static sert juste a etre vu par les autres fonctions present dans le fichier.
    Donc je dois l enlever pour qu il soit utiliser autre part.


    Dis moi il ne faudrait pas mettre le charactere '\0' a la fin ??

  5. #5
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    j ai toujours l erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x08053298 ***
    Aborted
    Je ne sais vraiment pas a quoi cela est du

  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 Mr_Chut
    j ai toujours l erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x08053298 ***
    Aborted
    Je ne sais vraiment pas a quoi cela est du
    Un problème ailleurs. (Débordement de tableau, par exemple...)

    Essaye d'isoler le code qui provoque ce problème à coup de
    c'est la méthode la plus rapide pour trouver ce genre de bug...

  7. #7
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    ok merci, apparement c'est ma liste qui deconne !!! pourtant avant je n avais pas ce probleme !

    Bref je vais voir de ce cote la.

    Au fait, j ai completement oublier de te le demander car en regardant ce matin d un oeil plus eveille, j ai vu dans la fonction str_concat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    .....
        size_t size = 1;
       { //<------- a quoi sert cette accolade et l autre qui lui est associee.
          const char *ct;
          va_list va;
          va_start (va, cs);
          while ((ct = va_arg (va, char *)) != NULL)
          {
             size += strlen (ct);
          }
          va_end (va);
       }
    ....
    Est on obligé de declarer 2 fois :
    const char *ct (surement parce que c est un const)
    va_list va

  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 Mr_Chut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    .....
        size_t size = 1;
       { //<------- a quoi sert cette accolade et l autre qui lui est associee.
    Vu qu'on parcourt 2 fois la liste, j'ai défini 2 zones de traitement indépendantes avec va_start/va_end(). C'est plus clair. {} définit un bloc. Les variables définies dans se bloc ont une portée limitée à celui-ci. Ca rend le code plus modulaires. Les blocs de traitement sont indépendants. Ca évite le recyclage sauvage de variables...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
          const char *ct;
          va_list va;
          va_start (va, cs);
          while ((ct = va_arg (va, char *)) != NULL)
          {
             size += strlen (ct);
          }
          va_end (va);
       }
    ....
    Est on obligé de declarer 2 fois :
    const char *ct (surement parce que c est un const)
    va_list va
    Je préfère faire comme ça, je suis certain que ça fonctionne.

  9. #9
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    c est vraiment bizarre...
    Le probleme vien du malloc de la fonction str_concat ....
    Il me le fait 3 fois, mais apres il me sort l erreur malloc() memry corruption.

    Je ne comprend pas je concat les chaine de caractere, pour avoir un path.
    Avec ce path je cree mon repertoire et apres je free la chaine de caractere path. Je ne vois pas pourquoi ca ne marche pas ....


    le pire c'est que j avais une ancienne fonction qui fonctionnait, par contre j avais un probleme das mon programme plus tard avec :

    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
    char *str_concat(char *cs, ...) {
    	va_list va;
    	const char *ct;
    	char *s = NULL;
    	size_t size = 0;
     
    	va_start(va, cs);
     
    	s = (char *) malloc((strlen(cs) + 1) * sizeof(char));
    	strcpy(s, cs);
     
    	while ((ct = va_arg(va, char *)) != NULL) 
    	{
    		size += strlen(ct) + strlen(s);
     
    		s = (char *) realloc(s, sizeof(char) * (size + 1));
    		if (s != NULL) 
    			strcat(s, ct);
    		else 
    		{
    			fprintf (stderr, "error realloc(): not enough memory.\n");
    			free (s);
    			s = NULL;
    			exit (EXIT_FAILURE);
    		}
    	}
     
    	return s;
    }
    et perso je prefere faire un malloc une seule fois que plusieurs realloc ....

  10. #10
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ceci fonctionne :
    Juste pour faire joli, je rajouterais un premier test pour assurer que cs n'est pas NULL, histoire de ne pas avoir de coredump sur un appel du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    s = str_concat(NULL);
    Il suffit que str_concat() renvoie NULL dans ce cas.

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Code C à éviter : Sélectionner tout - Visualiser dans une fenêtre à part
    s = (char *) realloc(s, sizeof(char) * (size + 1));
    Il ne faut pas faire ça, car si realloc() retourne NULL, s est toujours alloué mais perdu (fuite mémoire). Tu dois utiliser un temporaire.
    Code C non-testé : 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
    /* Retourne 0 si OK et -1 si erreur
       Nécessite un cast si le pointeur de départ n'est pas void*
       (mais bon, on peut toujours faire des wrappers pour les types courants) */
    int MonRealloc(void ** ppData, size_t taille)
    {
    	void *ptr = realloc(*ppData, taille);
    	if(ptr != NULL)
    		*ppData = ptr;
    	return (ptr==NULL ? -1 : 0);
    }
     
    /* Et comme je suis de bonne humeur, un petit wrapper pour char */
    static inline /*si supporté*/ int MonReallocChar(char ** ppData, size_t taille)
    {
    	return MonRealloc((void **)ppData, taille);
    }


    Code C suspect : Sélectionner tout - Visualiser dans une fenêtre à part
    size += strlen(ct) + strlen(s);
    un size += strlen(ct); (ou bien size = strlen(ct) + strlen(s) + 1;) ne suffirait-il pas ?

  12. #12
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    J ai trouvé ceci :
    Memory Corruption: Memory when altered without an explicit assignment due to the inadvertent and unexpected altering of data held in memory or the altering of a pointer to a specific place in memory.
    Je ne vois pas en quoi le malloc altere la memoire, vu que s dans la fonction est NULL et est de plus une variable locale.

  13. #13
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par Médinoc
    Code C à éviter : Sélectionner tout - Visualiser dans une fenêtre à part
    s = (char *) realloc(s, sizeof(char) * (size + 1));
    Il ne faut pas faire ça, car si realloc() retourne NULL, s est toujours alloué mais perdu (fuite mémoire). Tu dois utiliser un temporaire...
    Je ne l utilise plus, j utilise une autre maniere, je parcours une fois la liste des parametres et je calcul la taille total d 'un seul coup.
    Le probleme viens apparement du malloc qui me fais un memory cooruption

  14. #14
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    En rajoutant juste avant le while
    free(path); path = NULL;

    l erreur glibc memory vient des la premiere boucle (aulieu de boucler 3 fois avant de crasher)..

    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
     
    void init_dir(char *rep_dir_path, list_t l) 
    {
    	int path_len;
    	char *path;
     
    	path_len = strlen(rep_dir_path);
     
    	mkdir(rep_dir_path, S_IRWXU);
     
    	path = str_concat(rep_dir_path, "/Divers", NULL);
    	mkdir(path, S_IRWXU);
            free(path);                //  <--- Est ce bon  ??
            path = NULL;             //   <---
     
    	while (fdt_list != NULL) 
    	{
    		path = str_concat(rep_dir_path, "/", l->name, NULL);
    		mkdir(path, S_IRWXU);
    		l = l->next;
    		free(path);        //  <--- Est ce bon  ??
                    path = NULL;      //   <---
    	}
     
    }

  15. #15
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    J ai trouve !!!!!!!!!!!


    j avais pas allouer assez de memoire !!!


    je dois mettre

    aulieu de


  16. #16
    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 Mr_Chut
    je dois mettre
    aulieu de
    j'ai pas vu ça. Je suis bon pour la casse...

  17. #17
    Membre régulier

    Inscrit en
    Avril 2004
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 78
    Points : 74
    Points
    74
    Par défaut
    comme quoi la perfection n existe pas

    Merci quand meme pour ton aide ainsi qu aux autres.

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

Discussions similaires

  1. [SQL]Probleme avec chaine de caracteres
    Par acheo dans le forum Access
    Réponses: 4
    Dernier message: 31/03/2007, 22h28
  2. probleme extraction de chaine de caracteres
    Par nivose110 dans le forum C
    Réponses: 13
    Dernier message: 11/07/2006, 15h44
  3. probleme sur les chaines de caractere
    Par foufi5 dans le forum C
    Réponses: 8
    Dernier message: 22/12/2005, 15h30
  4. Pb Update avec chaine de caractere
    Par JuJu° dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 28/05/2003, 15h58
  5. Probleme sur les chaines de caractere
    Par scorpiwolf dans le forum C
    Réponses: 8
    Dernier message: 06/05/2002, 19h01

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