J'ai utilisé Valgrind pour trouver des fuites de mémoire dans mon programme. Les fonctions importantes sont les suivantes:Fuite de mémoire dans replaceAll in C
char *replaceAll (const char *string, const char *substr, const char *replacement){
char *tok = NULL;
char *newstr = NULL;
char *oldstr = NULL;
char *strhead = NULL;
// if either substr or replacement is NULL, duplicate string and let caller handle it
if (substr == NULL || replacement == NULL) return strdup (string);
newstr = strdup (string);
strhead = newstr;
while ((tok = strstr (strhead, substr))) {
oldstr = newstr;
newstr = malloc(strlen(oldstr) - strlen(substr) + strlen(replacement) + 1);
// failed to alloc mem, free old string and return NULL
if (newstr == NULL){
free (oldstr);
return NULL;
}
memcpy (newstr, oldstr, tok - oldstr);
memcpy (newstr + (tok - oldstr), replacement, strlen (replacement));
memcpy (newstr + (tok - oldstr) + strlen(replacement), tok + strlen (substr), strlen (oldstr) - strlen (substr) - (tok - oldstr));
memset (newstr + strlen (oldstr) - strlen (substr) + strlen (replacement) , 0, 1);
// move back head right after the last replacement
strhead = newstr + (tok - oldstr) + strlen(replacement);
free (oldstr);
}
return newstr;
}
et
int transformRegex(char **regexS){
char* retS;
retS = (char*) malloc(400);
memset(retS, 0x00, 400);
retS = replaceAll(*regexS, ".", "\\.");
if (strstr(*regexS, "*")) {
retS = replaceAll(retS, "**", "@");
retS = replaceAll(retS, "*", "[^\\.]ß");
retS = replaceAll(retS, "ß", "*");
retS = replaceAll(retS, "@", ".*");
}
if(strstr(*regexS, "%")){
retS = replaceAll(retS, "%", "[^\\.]{1}");
}
char tmpStr[strlen(retS)+3];
memset(tmpStr, 0x00, strlen(retS)+3);
memcpy(tmpStr, "^", 1);
memcpy(&tmpStr[1], retS, strlen(retS));
strcat(tmpStr, "$");
memcpy(*regexS, tmpStr, strlen(tmpStr));
free(retS);
return 0;
}
maintenant Valgrind me rapporte
==29218== 129 bytes in 5 blocks are definitely lost in loss record 6 of 9
==29218== at 0x4C27DD0: malloc (vg_replace_malloc.c:270)
==29218== by 0x400A64: **replaceAll** (regcomptest.c:44)
==29218== by 0x400C61: **transformRegex** (regcomptest.c:141)
==29218== by 0x400F9F: main (regcomptest.c:221)
==29218==
==29218== 134 bytes in 5 blocks are definitely lost in loss record 7 of 9
==29218== at 0x4C27DD0: malloc (vg_replace_malloc.c:270)
==29218== by 0x400A64: **replaceAll** (regcomptest.c:44)
==29218== by 0x400C34: **transformRegex** (regcomptest.c:136)
==29218== by 0x400F9F: main (regcomptest.c:221)
==29218==
==29218== 6,000 bytes in 15 blocks are definitely lost in loss record 9 of 9
==29218== at 0x4C27DD0: **malloc** (vg_replace_malloc.c:270)
==29218== by 0x400C07: **transformRegex** (regcomptest.c:132)
==29218== by 0x400F9F: main (regcomptest.c:221)
où la fiche 9 se réfère à l'appel malloc (400). Pourquoi est-ce 400 * , et pourquoi fuit-il quand je dis libre (retS)? Et comment puis-je l'implémenter correctement pour que replaceAll ne fuit pas la mémoire? Parce que transformRegex modifie le paramètre par référence, toutes les variables temporaires doivent être libérées à la fin de la fonction. Mais je n'ai aucune idée de comment, mon passé Java bloque en pensant en C;)
+1. Notez que 'retS' doit aussi être libéré après chaque appel à' replaceAll' – simonc
quand je le fais (libre après chaque replaceAll ou free (string)) je reçois des erreurs. Mon idée est d'avoir une variable auxiliaire retS qui est allouée une fois et libérée à la fin. Comment puis-je le libérer - après chaque remplacement - si je dois encore l'utiliser? – dasLort
@dasLort Vous pouvez utiliser un pointeur pour stocker le reS. comme char * reSS = reS. Puis reSS libre enfin –