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 :

Mauvaise allocation (bad_alloc)


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 17
    Par défaut Mauvaise allocation (bad_alloc)
    Bonjour,

    J'ai un problème de mémoire dans mon programme. VS me renvoie une exception bad_alloc sur la fonction get_Traj() suivante :

    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
    double * Processus_Ito::get_Traj(double h) const {
        //on simule une trajectoire du processus
        //on renvoie un tableau contenant les points (S_{t_i})
    	long N = (long) floor(T/h)+1;
        double * traj = new double[N];
        *SCurr=S0;
        traj[0]=S0;
    	double t=0;
        for(int i=0;i<N-1;i++)
        {
    		traj[i+1]=traj[i]+(*this).get_Increment(t,h);
            *SCurr=traj[i+1]; 
    		t+=DT;
        }
        return traj;
    }
    Je l'utilise à travers d'autres fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    double BarrierOption::Simule() const
    {
    	cout << "Récupération de la trajectoire"<<endl;
    	double * traj= S.get_Traj(S.getDT());
    	//on regarde si l'actif est sortie du domaine durant la
    	//durée de vie de l'option
    	int i=0;
    	while ((traj[i]>=bg) && (traj[i]<=bd) && (i<S.getN()))
    		i++;
    	if(i==S.getN())
    		return P(traj[S.getN()-1]);
    	else
    		return 0;
    }
    et

    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
    double* Processus::MonteCarlo(long NMC) const{
        double M=0,V=0;
        for(int i=0;i<NMC;i++)
        {
            double real = (*this).Simule();
            M+=real;
            V+=real*real;
        }
        M*=1./NMC;
        double var=1./(NMC-1)*V-NMC*M*M/(NMC-1);
    	double rvar=sqrt(var);
        double *ret = new double[4];
        ret[0]=M-rvar*1.96/sqrt((double)NMC);
        ret[1]=M;
        ret[2]=M+rvar*1.96/sqrt((double)NMC);
        ret[3]=var;
        return ret;
    }
    Quand je prend pour h (paramètre de get_Traj) la valeur 0.01 et pour NMC la valeur 10^7, mon programme calcule la valeur que j'attends. Par contre si je prends h=0.0001 et NMC=100000. L'exception est levée pour i=26669...
    Par ailleurs, si j'appelle get_Traj tout seul et que je copie le tableau renvoyé dans un fichier, tout se passe bien même pour h=0.0001.

    Auriez-vous une idée de l'origine du problème ? J'ai bien fait attention de détruire tous mes pointeurs dès que je le pouvais et pourquoi ça ne plante pas tous le temps ?

    Pour information, la classe Processus_Ito dérive la classe Processus et la classe BarrierOption a un membre S qui est un processus.

    Merci d'avance de votre aide.

    allced.

  2. #2
    Membre éclairé Avatar de cynique
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Par défaut
    Citation Envoyé par allced Voir le message
    Bonjour,

    J'ai un problème de mémoire dans mon programme. VS me renvoie une exception bad_alloc sur la fonction get_Traj() suivante :

    Quand je prend pour h (paramètre de get_Traj) la valeur 0.01 et pour NMC la valeur 10^7, mon programme calcule la valeur que j'attends. Par contre si je prends h=0.0001 et NMC=100000. L'exception est levée pour i=26669...
    Par ailleurs, si j'appelle get_Traj tout seul et que je copie le tableau renvoyé dans un fichier, tout se passe bien même pour h=0.0001.

    Auriez-vous une idée de l'origine du problème ? J'ai bien fait attention de détruire tous mes pointeurs dès que je le pouvais et pourquoi ça ne plante pas tous le temps ?
    Dans le code que j'ai vu, il n'y a pas de "delete" sur le variable "traj"...

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

    Merci d'avoir regardé mon code.

    Dans la méthode Simule j'ai toujours besoin des valeurs contenues dans traj... Donc je ne peux pas faire de delete avant mon return.
    Dans la méthode get_Traj, je renvoie le pointeur donc je peux pas le supprimer...

    QUand je disais que j'avais mis des delete, c'est dans d'autres parties du code ou je dois récupérer que certaines valeurs dans mon tableau, je les stockais dans des variables puis delete le pointeur.

    Auriez vous une idée ?

    Merci d'avance.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Ca plante certainement au moment où soit il n'y a plus de mémoire (1) soit tu en demandes trop (2).
    (1) Effectivement, je ne vois pas comment tu détruit traj dans Simulé:
    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
    double BarrierOption::Simule() const
    {
    	cout << "Récupération de la trajectoire"<<endl;
    	double * traj= S.get_Traj(S.getDT());
    	//on regarde si l'actif est sortie du domaine durant la
    	//durée de vie de l'option
    	int i=0;
    	while ((traj[i]>=bg) && (traj[i]<=bd) && (i<S.getN()))
    		i++;
    	if(i==S.getN())
    		return P(traj[S.getN()-1]);
    	else
    		return 0;
    // -> Ici traj est perdu ?
    }
    (2) Pour ton h très petit, que devient :T/h dans long N = (long) floor(T/h)+1; ?

    [EDIT] : pourquoi ne pas utiliser un std::vector dont tu réserverais la taille au départ ?

  5. #5
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 17
    Par défaut
    Salut,

    Dans Simule, je devrais faire ça ? :
    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
    double BarrierOption::Simule() const
    {
    	cout << "Récupération de la trajectoire"<<endl;
    	double * traj= S.get_Traj(S.getDT());
    	//on regarde si l'actif est sortie du domaine durant la
    	//durée de vie de l'option
    	int i=0;
    	while ((traj[i]>=bg) && (traj[i]<=bd) && (i<S.getN()))
    		i++;
    	if(i==S.getN())
    		return P(traj[S.getN()-1]);
    	else
    		return 0;
            delete traj;
    }
    ou alors avant mon if, je stocke la valeur finale du tableau dans une variable et je delete alors traj (on peut rien faire après un return, c'est bien ça ?).

    Si j'ai bien compris, dans Simule je ne détruis pas traj donc j'accumule des tableaux énormes ce que n'aime pas la machine ? Je ne peux pas corriger mon code et faire des tests maintenant mais dès que je peux je vous tiens au courant.

    Concernant l'utilisation de vector, je ne connais pas la stl. Je suis débutant en c++ mais je vais regarder ça de plus près.

    Merci.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par allced Voir le message
    Salut,

    Dans Simule, je devrais faire ça ? :
    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
    double BarrierOption::Simule() const
    {
    	cout << "Récupération de la trajectoire"<<endl;
    	double * traj= S.get_Traj(S.getDT());
    	//on regarde si l'actif est sortie du domaine durant la
    	//durée de vie de l'option
    	int i=0;
    	while ((traj[i]>=bg) && (traj[i]<=bd) && (i<S.getN()))
    		i++;
            double resultat(0.);
    	if(i==S.getN())
    		resultat = P(traj[S.getN()-1]);
            delete []traj;
            return resultat;
    }
    ou alors avant mon if, je stocke la valeur finale du tableau dans une variable et je delete alors traj (on peut rien faire après un return, c'est bien ça ?).
    Oui.
    Citation Envoyé par allced Voir le message
    Si j'ai bien compris, dans Simule je ne détruis pas traj donc j'accumule des tableaux énormes ce que n'aime pas la machine ?
    Oui. Le cas peut se produire aussi pour h très très petit (une demande d'allocation alors trop importante).

    Citation Envoyé par allced Voir le message
    Concernant l'utilisation de vector, je ne connais pas la stl. Je suis débutant en c++ mais je vais regarder ça de plus près.
    Pour être franc : si tu es débutant en C++, NE FAIS PAS de pointeur. Tournes-toi vers les conteneurs existant - comme std::vector.

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

Discussions similaires

  1. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  2. Réponses: 4
    Dernier message: 03/12/2002, 16h47
  3. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14
  4. Allocation de ressources
    Par Eric Pasquier dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 08/10/2002, 09h19
  5. Réponses: 3
    Dernier message: 04/09/2002, 09h42

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