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 :

Regex et perte de mémoire


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 34
    Par défaut Regex et perte de mémoire
    Bonjour, j'ai écris un programme utilisant des Regex en grande quantité.
    Ce programme consomme de plus en plus de mémoire.

    Cela semble lié à l'utilisation des Regex ( le programme prend régulièrement 4Ko pour 60 Regex effectuées ).

    J'utilise un code pris sur le net pour l'utilisation des Regex et j'utilise regFree pour libérer la mémoire.

    La seule modification que j'ai apportée est celle-ci :

    Ligne originale :

    pmatch=malloc(sizeof(*pmatch)*nmatch)

    que j'ai remplacé par :

    pmatch=(regmatch_t*)malloc(sizeof(*pmatch)*nmatch)

    car j'avais une erreur de type Can't convert Void* to regmatch_t* dans la ligne originale ...


    Est-ce que cela peut-être la cause de cette fuite de mémoire ???

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Cette erreur indique que tu compiles en C++.
    Retire ton cast et renomme ton fichier de .cpp à .c.

    Mais cette modification ne peut pas être à l'origine de la fuite de mémoire.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 34
    Par défaut
    Est-ce qu'il y a une méthode particulière ou des outils sous visual C++ pour identifier l'origine de cette perte de mémoire?

    J'ai libéré la majorité des variables utilisées, mais cette histoire de 4 ko toutes les 60 Regex, ça me parait bizarre ...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 34
    Par défaut
    Voilà la procédure qui perd de la mémoire (environ 80 octets par Regex , soit 4 ko pour la procédure en entier. Le motif est toujours juste donc la partie en rouge n'est pas en cause.

    La procédure sert à obtenir un codage phonétique d'un mot en faisant une suite de recherches de REGEX ( une centaine ) et à remplacer la cible par un caractère. ex : au -> O

    Je commence à devenir dingo , si quelqu'un pouvait m'aider ....



    char *codePhone(char *source){
    // Déclaration
    int longSource;
    int decal;
    char *reg_exp;
    int spos, epos;
    int err;
    int maxLine;

    phoneComment[0]=0;

    maxLine=codePhon[nivPhone].maxlinePhon;

    for(int numLin=0;numLin<maxLine;numLin++){

    reg_exp=codePhon[nivPhone].listePhon[numLin].ciblePhon;


    /*************************************************/
    int match=0;
    while(match==0){
    regex_t preg;

    err = regcomp (&preg,reg_exp, REG_EXTENDED); // compilation du motif avec recherche d'erreur

    if (err == 0) // pas d'erreur dans le motif
    {
    size_t nmatch=0;
    regmatch_t *pmatch = NULL;
    nmatch = preg.re_nsub; // Nombre d'occurence du motif trouvé

    /* Ligne originale
    pmatch = malloc (sizeof(*pmatch) * nmatch); */
    pmatch =(regmatch_t*) malloc (sizeof(*pmatch) * nmatch);


    match = regexec (&preg,source, nmatch, pmatch, 0); // Lancer la recherche
    regfree (&preg); // libérer la mémoire

    /*****************************/
    /* le motif a été trouvé */
    /*****************************/
    if (match == 0){

    spos = pmatch[0].rm_so;
    epos = pmatch[0].rm_eo;

    spos=spos+codePhon[nivPhone].listePhon[numLin].startCible;
    epos=spos+codePhon[nivPhone].listePhon[numLin].longCible;


    longSource=strlen(source);
    char *newPhon=codePhon[nivPhone].listePhon[numLin].newPhon;

    // Suppression des caractres inutiles par décalage ˆ gauche
    // remplacer boucle par stcpy (+rapide)??
    decal=epos-spos-strlen(newPhon);
    for(int k=epos;k<longSource;k++) source[k-decal]=source[k];
    source[longSource-decal]=0;
    // recopie de newPhon
    for(int k=0;k<strlen(newPhon);k++) source[spos+k]=newPhon[k];

    // Saut de lignes numLin=numLin+codePhon[nivPhone].listePhon[numLin].sautPhon;
    // Commentaires strncat(phoneComment,codePhon[nivPhone].listePhon[numLin].commentPhon,strlen(codePhon[nivPhone].listePhon[numLin].commentPhon));
    }

    /******************************/
    /* le motif n'a pas été trouvé */
    /******************************/
    else // if match==0
    if (match == REG_NOMATCH) {
    }

    else
    /*******************************/
    /* erreur dans le motif de recherche */
    /*******************************/
    { char *text;
    size_t size;

    size = regerror (err, &preg, NULL, 0);
    text = (char *)malloc (sizeof (*text) * size);
    if (text)
    { regerror (err,&preg, text, size);
    fprintf (stderr, "%s\n", text);
    free (text);
    }
    else
    { fprintf (stderr, "Memoire insuffisante\n");
    exit (EXIT_FAILURE);
    }

    } // fin test if match==0
    } // fin while (match==0)
    } // fin test err==0
    } // fin boucle numlin

    return source;

    }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    (examen en cours)
    Pourquoi as-tu remis le cast ?
    Coderais-tu en C++ ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    J'ai réindenté le code, et j'ai fait 2-3 modifs de déclarations de variables pour avoir moins d'erreurs de syntaxe sur un compilo C non-C99.
    Le code réindenté montre une erreur (on dirait une inversion) dans tes commentaires sur les accolades fermantes --> erreur d'algo ?

    Malheureusement, je ne peux pas faire plus, je suis sous Visual (pas de regexp).
    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
     
    char *codePhone(char *source)
    { 
    	// Déclaration
    	int longSource; 
    	int decal;
    	char *reg_exp;
    	int spos, epos;
    	int err;
    	int maxLine;
    	int numLin;
     
    	phoneComment[0]=0;
     
    	maxLine=codePhon[nivPhone].maxlinePhon;
     
    	for(numLin=0 ; numLin<maxLine ; numLin++)
    	{
    		int match=0;
     
    		reg_exp=codePhon[nivPhone].listePhon[numLin].ciblePhon;
     
     
    		/*************************************************/ 
    		match=0;
    		while(match==0)
    		{ 
    			regex_t preg;
     
    			err = regcomp(&preg,reg_exp, REG_EXTENDED); // compilation du motif avec recherche d'erreur 
     
    			if(err == 0) // pas d'erreur dans le motif
    			{
    				size_t nmatch=0; 
    				regmatch_t *pmatch = NULL; 
    				nmatch = preg.re_nsub; // Nombre d'occurence du motif trouvé
     
    				pmatch = malloc (sizeof(*pmatch) * nmatch);
     
    				match = regexec (&preg,source, nmatch, pmatch, 0); // Lancer la recherche
    				regfree (&preg); // libérer la mémoire
     
    				/*****************************/
    				/* le motif a été trouvé */
    				/*****************************/
    				if(match == 0)
    				{ 
    					char *newPhon = NULL;
    					int k;
     
    					spos = pmatch[0].rm_so;
    					epos = pmatch[0].rm_eo;
     
    					spos=spos+codePhon[nivPhone].listePhon[numLin].startCible;
    					epos=spos+codePhon[nivPhone].listePhon[numLin].longCible; 
     
     
    					longSource=strlen(source);
    					newPhon=codePhon[nivPhone].listePhon[numLin].newPhon;
     
    					// Suppression des caractères inutiles par décalage ˆ gauche
    					// remplacer boucle par stcpy (+rapide)??
    					decal=epos-spos-strlen(newPhon);
    					for(k=epos ; k<longSource ; k++)
    						source[k-decal]=source[k];
    					source[longSource-decal]=0; 
    					// recopie de newPhon
    					for(k=0 ; k<strlen(newPhon) ; k++)
    						source[spos+k]=newPhon[k];
     
    					// Saut de lignes numLin=numLin+codePhon[nivPhone].listePhon[numLin].sautPhon; 
    					// Commentaires strncat(phoneComment,codePhon[nivPhone].listePhon[numLin].commentPhon,strlen(codePhon[nivPhone].listePhon[numLin].commentPhon));
    				}
    				/******************************/
    				/* le motif n'a pas été trouvé */
    				/******************************/
    				else // if match==0
    					if (match == REG_NOMATCH)
    					{
    					}
    					else 
    					{ 
    						/*******************************/
    						/* erreur dans le motif de recherche */
    						/*******************************/
    						char *text;
    						size_t size;
     
    						size = regerror (err, &preg, NULL, 0);
    						text = malloc (sizeof (*text) * size);
    						if (text)
    						{
    							regerror (err,&preg, text, size);
    							fprintf (stderr, "%s\n", text);
    							free (text);
    						}
    						else
    						{
    							fprintf (stderr, "Memoire insuffisante\n");
    							exit (EXIT_FAILURE);
    						}
    					} // fin test if match==0
     
    			} // fin while (match==0)
    		} // fin test err==0 
    	} // fin boucle numlin
     
    	return source;
     
    }
    PS: Les erreurs de compilation montrent que tu utilises beaucoup de variables globales...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. regex et perte de mémoire
    Par OrthoMaker dans le forum Débuter
    Réponses: 5
    Dernier message: 16/04/2010, 22h43
  2. Probleme perte de mémoire - Chilkat
    Par Olphébus dans le forum Débuter
    Réponses: 5
    Dernier message: 05/08/2008, 01h16
  3. Réponses: 11
    Dernier message: 16/07/2007, 16h33
  4. Perte de mémoire - je ne comprend pas.
    Par pilouface dans le forum C
    Réponses: 12
    Dernier message: 08/02/2007, 16h39
  5. Pertes de mémoire avec Rave
    Par stepschn dans le forum Delphi
    Réponses: 8
    Dernier message: 15/10/2006, 11h18

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