Problème de mémoire [C]

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J’ai une fonction f (char* mot, ...) -> int qui parcourt un fichier et effectue des comparaisons entre le mot avec les les lignes du fichier (j’utilise donc beaucoup strcmp dans f). Je ne met pas le code parce-que f utilise d’autres fonctions et donc ça a peu d’intérêt.

Mon problème est le suivant : j’ai une fonction rN (char* word) -> char* qui supprime le caractère \n à la fin d’un mot si il existe. J’ai besoin que rN fasse cela sans modifier le mot en paramètre. J’ai donc ça :

char* rmN (char* word){
    static char* copiedStr = NULL;
    free(copiedStr);
    copiedStr = malloc(strlen(word)+1);
    strcpy(copiedStr, word);
    
    char* newName = copiedStr;
    unsigned long len = strlen(newName)-1;
    
    if (newName[len] == '\n'){
        newName[len] = 0;
    }
    
    return newName;
}

Le problème c’est qu’à la fin je free pas rN. Donc cette fonction n’est pas tip top. Je me suis dis que ça n’était pas grave, pourtant lorsque je fais : f (rN("a\n"), ...) j’obtiens un résultat différent de f ("a", ...) et je ne comprends pas pourquoi ?

Pensez-vous que c’est du à un problème de mémoire ? Si c’est le cas comment améliorer la fonction rN pour éviter cela ?

Merci beaucoup !

+0 -0

Cette réponse a aidé l’auteur du sujet

Oui, et c’est dans le cas où il n’y aurait pas de \n en fin de chaîne, et donc aucun caractère à supprimer.

Le problème c’est qu’à la fin je free pas rN

InaDeepThink

Mais il y a une raison particulière qui t’empêche de le faire (en supposant que tu n’utilises plus une variable statique et donc que tu retires le free dans la fonction) ?

lorsque je fais : f (rN("a\n"), ...) j’obtiens un résultat différent de f ("a", ...) et je ne comprends pas pourquoi ?

InaDeepThink

Quelle est la différence que tu obtiens ?

Est-ce que tu utilises plusieurs retours de ta fonction rnM en simultané ?

Édité par entwanne

Il y a aussi le "free(copiedStr);" qui ne sert à rien, copiedStr étant initialisé à NULL la ligne d’avant, tu ne libérera jamais rien avec cette appel à free().

Peut tu effectivement dire quels résultats tu obtient? Tu devrait normalement obtenir "a\0\0" si il y avait un "\n" et "a\0" si il n’y en avais pas, non?

Édité par Supertux

+0 -0

Il y a aussi le "free(copiedStr);" qui ne sert à rien, copiedStr étant initialisé à NULL la ligne d’avant, tu ne libérera jamais rien avec cette appel à free().

Supertux

La variable étant statique, elle n’est initialisée qu’une fois, donc free libère à chaque appel la mémoire allouée par l’appel précédent. C’est peut-être la cause de son problème s’il continue d’utiliser cette mémoire qui a été libérée.

Cette réponse a aidé l’auteur du sujet

Oh lala.

Tu as consciences @InaDeepThink que ta fonction, bien qu’elle fonctionne (🤔), ne permet d’utiliser 2 fois le résultat en même temps ?

En gros:

  printf("%s %s", rN("a\n"), rN("a"));

Ne donnera rien de correcte car un des deux retours de fonction sera libéré avant d’être utiliser par printf et donc invalide.

Pour s’en servir, on est obligé de faire comme ceci:

  char* t = strdup(rN("a\n"));
  printf("%s %s", t, rN("a"));
  free(t);

Avec strdup la fonction POSIX, _strdup sous Windows. Un malloc + un strcpy.

Il y a aussi un problème si on lui passe une chaîne de caractère vide et comme ça été dit avant la vérification du retour de malloc. Au passage, tu devrais utiliser strcpy_s et gérer les cas où on te passe une valeur NULL.

Édité par ache

ache.one                 🦹         👾                                🦊

+0 -0
Auteur du sujet

Désolé pour le retard j’ai eu des problèmes de connexions.

Merci beaucoup pour vos réponses.

Vu que manifestement tu ré-initialises la variable copiedStr à chaque call à la fonction, pourquoi diable en faire une variable statique ? (Et contrôle le retour de ton appel à malloc).

Et bien effectivement le problème venait de la variable en static . En enlevant le static ma fonction marche bien. Au début je mettais la variable en static car ça me permettait de faire : free(rmN(""));.

Tu as consciences @InaDeepThink que ta fonction, bien qu’elle fonctionne (🤔), ne permet d’utiliser 2 fois le résultat en même temps ?

Non je n’avais pas remarqué ce comportement :euh: et c’est justement pour ça que j’obtenais deux résultats différents du coup.

Il y a aussi un problème si on lui passe une chaîne de caractère vide et comme ça été dit avant la vérification du retour de malloc. Au passage, tu devrais utiliser strcpy_s et gérer les cas où on te passe une valeur NULL.

Oui, mais normalement c’est bon car je m’assure que mes chaînes de caractères ne sont pas vides dans f.

+0 -0

Du coup ta fonction doit ressemblé à ça :

char* rmN (char* word){
    char* copiedStr = NULL;
    unsigned long len = strlen(word);
    copiedStr = malloc(len+1);
    if( copiedStr == NULL )
       return NULL;
    strcpy(copiedStr, word);
    
    
    if (len > 0 && newName[len - 1] == '\n'){
        newName[len - 1] = 0;
    }
    
    return newName;
}

Attention du coup à ne pas oublier de libérer le retour de cette fonction.

ache.one                 🦹         👾                                🦊

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte