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 :

Les allocations mémoire


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2007
    Messages
    204
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2007
    Messages : 204
    Points : 89
    Points
    89
    Par défaut Les allocations mémoire
    Bonjour à tous,

    Sujet vaste qu'est l'allocation mémoire, je n'ai pas trouvé de meilleur titre, désolé.

    Je m'inquiète depuis peu (mieux vaut tard que jamais comme on dit), des fuites de mémoire sur mon projet. J'avais déjà l'habitude de faire assez attention aux malloc/new et aux free/delete, mais j'ai forcément du en oublier par ci par là...

    J'aurais donc quelques questions concernant le sujet, je n'ai rien trouvé de précis à ce niveau là sur internet :

    - Les fuites de mémoire provoquent une Segfault à partir d'un certain montant de mémoire fixe, ou est-ce aléatoire? (Mon projet à déjà planté à partir de 2.000k de mémoire ou 5.000k, donc je ne sais pas si c'était une mauvaise allocation ou juste que la mémoire "explose");
    - J'ai déjà essayé de libérer un char* que j'avais malloc uniquement à 2 (x taille d'un char*...), et BIM Segfault. On ne peut pas libérer les variables trop petites?
    - J'utilise pas mal de vecteurs de char*. Comment les libérer efficacement? Uniquement vecteur.clear()? Ou avant ça une boucle pour vider chaque élément?
    - J'utilise aussi pas mal de sprintf pour formater mes chaines. Et j'ai un cas qui m'arrive assez souvent, où je récupère dans un char* le résultat d'une méthode, puis je me sert de ce char* (et d'autres) dans un sprintf. Dois-je uniquement libérer le dernier char* (sur lequel on a effectué le sprintf), ou chacuns des éléments le composant?

    Dur dur de m'exprimer je vous joins un peu de code pour la dernière question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char* GetLaString()
    {
    	char* string_un   = MaMethode1();
    	char* string_deux = MaMethode2();
     
    	char* string_final = (char*)malloc(strlen(string_un)+strlen(sting_deux)+2);
    	sprintf(string_final, "%s_%s", string_un, string_deux);
     
    	return string_final;
    }
    Il me faut uniquement libérer string_final une fois que j'aurais appelé ma méthode? Ou faut-il que je libère aussi ses composants string_un et string_deux?

    Merci d'avance, et si vous avez des précisions à rajouter, n'hésitez pas

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Tu es en C++, donc la mémoire c'est new/new[]/delete/delete[] et non malloc et free.
    Pour la même raison,
    J'utilise aussi pas mal de sprintf pour formater mes chaines. Et j'ai un cas qui m'arrive assez souvent, où je récupère dans un char* le résultat d'une méthode, puis je me sert de ce char* (et d'autres) dans un sprintf. Dois-je uniquement libérer le dernier char* (sur lequel on a effectué le sprintf), ou chacuns des éléments le composant?
    on utilise std::string et non char*.

    Les fuites de mémoire provoquent une Segfault à partir d'un certain montant de mémoire fixe, ou est-ce aléatoire? (Mon projet à déjà planté à partir de 2.000k de mémoire ou 5.000k, donc je ne sais pas si c'était une mauvaise allocation ou juste que la mémoire "explose");
    Un segfault c'est un accès à de la mémoire désallouée en général.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char* ptr = new char;
    delete char;
    *ptr = 2;
    char* pptr;
    *pptr = 4;
    J'ai déjà essayé de libérer un char* que j'avais malloc uniquement à 2 (x taille d'un char*...), et BIM Segfault. On ne peut pas libérer les variables trop petites?
    Tu as plus certainement refait un free sur un pointeur déjà libéré.

    J'utilise pas mal de vecteurs de char*. Comment les libérer efficacement? Uniquement vecteur.clear()? Ou avant ça une boucle pour vider chaque élément?
    cf plus haut : vecteur de string.
    Et la règle est simple : si tu alloues dynamiquement, il faut le désallouer. Que ce soit une variable seule ou contenue dans un container.

    Il y a de nombreuses discussions sur ce forum sur la gestion mémoire
    On débat en gros les principes de la responsabilité et les smart pointer en particulier.

    Dans ton exemple, la méthode doit libérer string1 et 2, qui d'autre le pourrait ?
    Et c'est l'appelant qui a la responsabilité de libérer la chaîne retournée.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2007
    Messages
    204
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2007
    Messages : 204
    Points : 89
    Points
    89
    Par défaut
    Ok merci pour ta réponse!

    Par contre, le coup du on utilise des string, sa ne m'aide pas car j'ai des contraintes dans mon environnement de travail, et je ne peux pas m'en servir.
    C'est pourquoi je voulais savoir comment sa fonctionne avec les char*.

    De plus, le fait d'utiliser new et delete sur des variables autre que des objets, sa change quoi à malloc et free? Car j'ai lu pas mal de choses concernant ce sujet, et à part des réponses du style "Malloc c'est du C, New c'est du C++, donc pose pas de questions et obéit", je n'ai rien trouvé de très concret.

    Si je dois changer de section j'irais poser ma question dans le forum C et non C++, faites le moi savoir.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    En C tu écriras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* str = malloc(sizeof(char) * (len+1));
    où len correspond au nombre de caractère de la chaîne.
    En C++ on écrira
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* str = new char[len+1];
    Si demain tu ne veux plus utiliser char mais un nouveau type que tu auras créé par exemple, le code C++ sera plus sur puisque tu auras une erreur de compilation avec cette syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct MyChar { char[256]; };
    MyChar* str = new char[len+1];
    Alors que le code C compilera toujours à priori:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyChar* str = malloc(sizeof(char) * (len+1));
    Mais le résultat devrait être surprenant.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Citation Envoyé par CleeM Voir le message
    De plus, le fait d'utiliser new et delete sur des variables autre que des objets, sa change quoi à malloc et free? Car j'ai lu pas mal de choses concernant ce sujet, et à part des réponses du style "Malloc c'est du C, New c'est du C++, donc pose pas de questions et obéit", je n'ai rien trouvé de très concret.
    Voir la FAQ : Pourquoi utiliser new plutôt que malloc ? En gros, ça fait pas exactement la même chose (même si dans ton cas, avec char, ça ne change rien)

    Citation Envoyé par CleeM Voir le message
    Par contre, le coup du on utilise des string, sa ne m'aide pas car j'ai des contraintes dans mon environnement de travail, et je ne peux pas m'en servir.
    C'est pourquoi je voulais savoir comment sa fonctionne avec les char*
    En fait, ton erreur n'est pas (uniquement) de mélange du C et du C++, mais c'est surtout que tu n'utilises pas l'un des points fort du C++ : le RAII (voir la FAQ : Comment gérer proprement des allocations / désallocations de ressources ? Le RAII !)
    Le fait de ne pas pouvoir utiliser std::string peut arriver, surtout sur des environnement un peu exotique. Par contre, ne pas encapsuler tes chaînes dans une structure, c'est une mauvaise pratique. Si tu n'as pas accès à std::string, alors il faut que tu créés ta propre classe String (ce n'est pas très compliqué).

    L'idée est qu'il est facile d'oublier des delete/free (ou qu'il est parfois compliqué de définir une politique de gestion des ressources claire et que l'on sait pas très bien où et quand libérer les ressources), on délègue alors la responsabilité de faire le ménage à une classe spécifique. Dit autrement, la libération des ressources est une responsabilité à part entière et donc, par respect du principe de responsabilité unique (SRP), cette responsabilité doit être géré par une classe dédiée (string, vector, smart pointers par exemple pour la STL)

    Bref, créé toi des classes utilitaires si tu ne peux pas utiliser la STL

    HS : c'est étonnant que tu aies droit aux vecteurs, mais pas aux string. Ou alors tu utilises ta propre classe Vector ?

Discussions similaires

  1. Allocation mémoire avec les conteneurs
    Par Yellowmat dans le forum SL & STL
    Réponses: 4
    Dernier message: 08/03/2010, 14h00
  2. Réponses: 8
    Dernier message: 03/02/2007, 12h20
  3. Allocation mémoire
    Par DestyNov@ dans le forum C++
    Réponses: 9
    Dernier message: 23/08/2005, 08h09
  4. [Pointeur] Allocation mémoire
    Par Rayek dans le forum Langage
    Réponses: 22
    Dernier message: 20/05/2005, 10h26
  5. Allocation mémoire dynamique
    Par ITISAR dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 21/01/2005, 09h59

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