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 :

gestion memoire set_new_handler ne marche pas


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 58
    Par défaut gestion memoire set_new_handler ne marche pas
    Salut a tous,

    j'ai un petit probleme de memoire avec mon programme (qui en fait n'est pas vraiment le mien :p )
    en gros, il fait plein de truc avec des new qui ne sont certainement pas deleté, mais bon, ceci est un autre probleme.

    ce que j'aimerai, c'est qu'au lieu qu'il me fasse un "memoire insuffisante", je puisse executer un bout de code a moi, donc j'ai utilisé set_new_handler, mais ca ne marche pas

    voila la partie concernée
    tout se passe dans la meme classe:

    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
    int  deborde(unsigned int)//FT221
    {
    AfxMessageBox("plop");
    return 0;
    }
     
    int CThread::Run()
    {
    (....)
    _set_new_handler(deborde);
    char* toto;
    for (int a=0;a<1000;a++)
    	toto=new char[500000000];
    (....)
    }
    j'ai essayé tout et n'importe quoi, ca, ca compile mais arrivé sur le set_new_handler, il ne met pas apparemment a jour la fonction a appeler.
    donc lorsque je le lance, il me met toujours "memoire insuffisante" au lieu d'aller dans ma fonction deborde j'ai essayé tout ce que j'ai trouvé sur le net, mais rien ne marche

    je tourne sur XP avec visuel c++ 6.
    c'est une appli graphique, mais on dirait que l'un de mes collegues a reussi en mode console, mais impossible de le faire passer sur l'appli

    merci a tous

    mike

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    La solution la meilleure consisterait sûrement à commencer par... traquer les fuites mémoires

    De plus, set_new_handler fait partie, à moins que tu n'utilises un compilateur "antediluvien", de l'espace de nommage std...

    Cela voudrait dire que ton code devrait plutot etre du genre de (bien que je n'ai jamais eu recours à cette fonction, et que mon exemple risque donc d'être faux)
    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
     
    int deborde(unsigned int)//FT221 
    {
        AfxMessageBox("plop");
        return 0;
    }   
    int CThread::Run()
     {
        /* (...) */
        std::_set_new_handler(deborde); 
        char* toto; 
        for (int a=0;a<1000;a++)  
            toto=new char[500000000]; 
        /*(....)*/
    }
    le tout, sans préjudice évidemment des erreur que ton code pouvait contenir à la base.

    D'un autre coté, il faut savoir que, normalement, si new échoue par manque de mémoire, il va lancer une exception de type std::bad_alloc

    L'avantage des exceptions, c'est, entre autre, qu'elles remontent la pile d'appel jusqu'à ce qu'elles soient gérées dans un bloc catch.

    Rien ne t'empêche donc d'envisager quelque chose qui prendrait une forme proche de
    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
     
    void Fonction1(CThread& t)
    {
        t.Run() /* ce serait ici que bad_alloc serait lancé */
     
    }
    void Fonction2()
    {
        CThread t1;
        /* ...*/
        Fonction2(t1);
        /* peut etre que dans cette fonction tu ne sait pas gérer entierement
         * l'exception... c'est pas grave, on la "laisse filer" ;) */
    }
    int Fonction3()
    {
        /* C'est dans cette fonction que l'on peut gérer l'exception... on place
         * donc ce qui peut en lancer une dans un bloc try/catch */
        try
        {
             /*...*/
             Fonction1();
             /*...*/
        }
        catch(std::bad_alloc &e)
        {
            AfxMessageBox("débordement de mémoire");
            /* si on ne peut malgré tout gérer qu'une partie de l'exeption, rien
             * n'empeche de la relancer */
           throw e;
           /*  ... ou d'en relancer une autre ;) */
           throw TaPropreException;
        }
    }
    Enfin, si je comprend que ton exemple a principalement pour but de forcer l'exception, je ne rappellerai jamais assez le fait qu'il est très largement préférable d'utiliser la classe std::string plutôt que de s'amuser avec des tableaux de caractères à la "C style"

    Même si le but est d'envoyer la chaîne de caractères à une fonction écrite en C, toute la gestion de chaîne devrait être faite au départ de la std::string, convertie au dernier moment en tableau de caractères C style à l'aide de la méthode c_str()
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 58
    Par défaut
    Salut koala01,

    je suis du meme avis que toi qu'il faudrait deja corriger les fuites, car il doit y en avoir un paquet, mais bon, ce n'est malheureusement pas moi qui decide de ce que je dois faire (je ne suis qu'apprenti dans la boite). et corriger les fuites memoires de 5000 lignes de codes.... (oui, fonction horrible, mais j'ai malheureusement pas le choix, c'est moi qui doit reparer les erreurs des autres )

    j'avais deja essayé avec le std:: devant, mais il me dit que set_new_handler (ou avec le _ ) n'est pas connu dans std.

    apres avoir fait quelques tests en debug, je remarque qu'il ne met pas en memoire la bonne adresse de fonction la je comprends pas....
    j'ai essayé avec des & dans le set_new_handler mais pas mieux.

    pour l'histoire du catch, malheureusement ca ne peux pas me convenir, car contrairement au set_new_handler, il ne continue pas apres.
    car le but de la fonction deborde, sera de liberer de la memoire prevue a cet effet ( quelques centaines de Mo reservées puis qui seront libérés pour permettre de finir le tour de boucle malheureusement indispensable sinon le resultat ne sera pas beau a voir ^^ )

    pour les char* ... c'est juste un test pour remplir la memoire et voir si ca passe dans la fonction prevue... mais pour le moment non

    merci quand meme, et si t'as d'autres idées, infos etc.. n'hesite toujours pas, je suis preneur :p

    mike

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par mikeOSX
    j'avais deja essayé avec le std:: devant, mais il me dit que set_new_handler (ou avec le _ ) n'est pas connu dans std.
    Tu as bien inclu <new> ?

    Note VC++6 est antedeluvien; datant d'avant la norme (qui aura bientot 10 ans), il la respecte peu d'apres ce que j'ai compris (note: je n'ai jamais reellement programme pour Windows).

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Tu as bien inclu <new> ?

    Note VC++6 est antedeluvien; datant d'avant la norme (qui aura bientot 10 ans), il la respecte peu.
    Oupps, je n'avais même pas remarqué qu'il indiquait travailler avec VC++ 6
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par mikeOSX
    Salut koala01,

    je suis du meme avis que toi qu'il faudrait deja corriger les fuites, car il doit y en avoir un paquet, mais bon, ce n'est malheureusement pas moi qui decide de ce que je dois faire (je ne suis qu'apprenti dans la boite).
    (c'est peut etre l'occasion de montrer ce que tu sais faire )
    et corriger les fuites memoires de 5000 lignes de codes.... (oui, fonction horrible, mais j'ai malheureusement pas le choix, c'est moi qui doit reparer les erreurs des autres )
    Peuh... mais sur 5000 lignes de code, ca se fait tout seul
    j'avais deja essayé avec le std:: devant, mais il me dit que set_new_handler (ou avec le _ ) n'est pas connu dans std.

    apres avoir fait quelques tests en debug, je remarque qu'il ne met pas en memoire la bonne adresse de fonction la je comprends pas....
    j'ai essayé avec des & dans le set_new_handler mais pas mieux.
    Je t'avais prévenu ne pas etre du tout familier avec cet oiseau là
    pour l'histoire du catch, malheureusement ca ne peux pas me convenir, car contrairement au set_new_handler, il ne continue pas apres.
    car le but de la fonction deborde, sera de liberer de la memoire prevue a cet effet ( quelques centaines de Mo reservées puis qui seront libérés pour permettre de finir le tour de boucle malheureusement indispensable sinon le resultat ne sera pas beau a voir ^^ )
    Heu... défini "ne continue pas apres"...

    Ainsi que je te l'ai indiqué, l'opérateur new lance lui meme l'exception bad_alloc si l'allocation échoue...

    De plus, rien ne t'oblige à relancer une exception qui a été gérée, ainsi que le montre le petit 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
    #include <iostream>
    #include <stdexcept>
    using namespace std;
     
    int main()
    {
        try
        {
            cout<<"lancement d'une exception (ici bad alloc)"<<endl;
            throw bad_alloc();
        }
        catch(...)
        {
            cout<<"toutes les exceptions ont été prises ici"<<endl;
        }
        cout<<"le programme a continué sans probleme"<<endl;
        return 0;
    }
    Du coup, rien ne t'empêche de travailler sous une forme proche de
    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
     
    int CTrhead::Run()
    {
        type *mavar;
        /*...*/
        try
        {
            mavar=new type[/*le bon nombre */];
        }
        catch(std::bad_alloc &e)
        {
            /* la gestion consiste ici à trouver suffisamment de mémoire pour
             * que l'allocation réussisse cette fois et à réessayer
             */
     
             mavar=new type[/*...*/];
        }
    /* ce qui doit être fait une fois que l'on est sur d'avoir l'espace ;) */
    }
    pour les char* ... c'est juste un test pour remplir la memoire et voir si ca passe dans la fonction prevue... mais pour le moment non
    Je l'avais bien deviné, mais je tenais à rappeler l'idée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 58
    Par défaut
    oui, j'avais bien inclu new sinon, je pense que ca n'aurait pas marché a la compil
    et pour le VC++ 6 qui est antedeluvien, va dire ca a mes boss qui payent la licence !!


    bon, l'un de mes collegues (il est trop fort !! ) a trouvé le truc...

    c'est debile car c'est ecrit nul part.
    il faut juste rajouter un
    _set_new_mode(1);

    le code qui marche est donc

    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
    int deborde(unsigned int)//FT221 
    { 
    AfxMessageBox("plop"); 
    return 0; 
    }
     
    int CThread::Run() 
    { 
    // (....) 
    _set_new_mode(1);
    _set_new_handler(deborde); 
    char* toto; 
    for (int a=0;a<1000;a++)  
    toto=new char[500000000]; 
    (....) 
    }
    voila

    merci en tout cas pour votre aide

    mike

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par mikeOSX
    pour le VC++ 6 qui est antedeluvien, va dire ca a mes boss qui payent la licence
    Raisonnement stupide. Je parie que le cout d'une version a jour (1600 euros TTC sur LDLC si je ne me trompe pas -- ce qui est possible, je ne connais pas les produits MS) ne fait pas 5% du cout annuel d'un developpeur. Et vu le temps que vous devez perdre a contourner des problemes... continuer a l'utiliser doit vous couter plus que vous n'economisez.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Raisonnement stupide. Je parie que le cout d'une version a jour (1600 euros TTC sur LDLC si je ne me trompe pas -- ce qui est possible, je ne connais pas les produits MS) ne fait pas 5% du cout annuel d'un developpeur. Et vu le temps que vous devez perdre a contourner des problemes... continuer a l'utiliser doit vous couter plus que vous n'economisez.
    Ouaip, mais bon, tu sais... y a des patrons qui... bon, ne soyons pas médisants: ils sont gentils...

    Si le fait de s'arranger pour résoudre les problèmes de fuites de mémoire est de nature à faire plaisir au patron, en tant qu'apprenti, il risque vraiment de se faire mal voir s'il va crier chez le boss, en tapant le poing sur la table, qu'il faut acheter la mise à jour
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. [SDL] Gestion des événements ne marche pas
    Par lucas-84 dans le forum SDL
    Réponses: 5
    Dernier message: 17/11/2010, 14h18
  2. [AC-2003] Mon Module de gestion des états ne marche pas
    Par sebac dans le forum IHM
    Réponses: 9
    Dernier message: 27/11/2009, 10h33
  3. Gestion d'événements qui ne marche pas
    Par shkyo dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 11/01/2008, 15h57
  4. barette memoire qui marche pas
    Par bassam0205 dans le forum Périphériques
    Réponses: 9
    Dernier message: 30/11/2007, 08h12
  5. Réponses: 4
    Dernier message: 30/12/2004, 18h04

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