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 :

Référence et delete


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut Référence et delete
    Bonjour,

    j'obtiens une erreur dans le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    OPTRES* g_OptPty = NULL;
    ...
     
    g_OptPty = &Option_Call(...);
     
    delete g_OptPty
    Où Option_Call est une fonction qui renvoie un OPTRES :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    OPTRES Option_Call(double& _Under, double& _Strike, double& _RiskFreeRate, double& HistVol, double& Time)
    {
    	OPTRES	l_Res;
     
    	....
     
    	return l_Res;
    }
    Ce code compile, mais plante au delete. Je n'arrive pas à me convaincre du pourquoi le delete n'a pas sa place ici ; c'est donc que je ne comprend pas bien ce qui se passe : pourriez-vous m'éclairer ?

    Autre chose, je souhaite que mon code soit aussi rapide que possible, et donc réalise le moins de création/destructions d'objets et accès en écriture (d'où le passage par références). J'ai donc choisi de déclarer g_OptPty comme un pointeur dans le main pour ne pas allouer un objet inutilement, mais en échange, j'aurais un accès mémoire à chaque fois que j'accéderai à un membre.
    De même, la fonction Option_Call crée un objet OPTRES à l'intérieur, puis le renvoie. Mais est-ce la meilleure solution ? Ne devrais-je pas passer un argument supplémentaire (genre pOut), par référence, et travailler dessus ?

    Bref, dans l'optique adoptée, quelles sont les techniques utilisées en pratique ? Que feriez-vous ?

    Merci

    Cordialement
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  2. #2
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 900
    Points : 1 918
    Points
    1 918
    Par défaut
    Il te faut créer un objet dynamiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    OPTRES* g_OptPty = NULL;
    ...
     
    g_OptPty = new OPTRES(Option_Call(...));
     
    delete g_OptPty
    Ou alors, c'est ta fonction qui doit renvoyer un objet créé dynamiquement (pas toujours très prudent, dans la mesure où tu découples le new et le delete) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    OPTRES* Option_Call(double& _Under, double& _Strike, double& _RiskFreeRate, double& HistVol, double& Time)
    {
    	OPTRES*	l_Res = new OPTRES;
     
    	....
     
    	return l_Res;
    }
    Mais sinon : as-tu vraiment besoin d'un pointeur, ou un objet simple est-il suffisant ? Que fais ta fonction ? Est-ce-qu'elle renvoie un objet en fonction d'un certain nombre de paramètres externe, ou est-ce-qu'elle se contente de plagier le travail du constructeur ?

    Pourquoi ça plante : quand tu entres dans ta fonction, tu crées un objet. Quand tu sors de ta fonction, une copie de cet objet est créée et renvoyée, puis le premier objet est détruit. Puis le pointeur reçoit l'adresse de l'objet renvoyé, grâce au '&' devant l'appel à ta fonction, puis cet objet est détruit. Moralité, quand tu arrives au delete, le pointeur pointe sur un objet qui a été créé sur la pile, et qui n'existe plus => erreur de segmentation. Enfin, je ne suis pas à 100% sûr des étapes, de toutes les créations, mais l'idée générale c'est qu'à la fin tu fais un delete sur un pointeur invalide.

  3. #3
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    A ta place je créerais d'abord l'objet, puis le passerais par référence à la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    OPTRES g_OptPty;
    ...
     
    Option_Call(g_OptPty);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Option_Call(/*paramètres habituels, */ OPTRES& myOPTRES)
    {
        // utilisation de myOPTRES, exemple:
        myOPTRES.faisCeci();
        myOPTRES.faisCela();
    }
    Dans ton main, à la sortie de la fonction, celle-ci aura bien modifié ton objet OPTRES. Tu n'as donc qu'un constructeur, et pas la peine de s'embêter avec des pointeurs ou de l'allocation dynamique de mémoire.
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  4. #4
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Points : 68
    Points
    68
    Par défaut
    Un compilateur avec les bons warnings activés t'aurait d'ailleurs prévenu que tu prenais l'adresse d'un objet temporaire (autrement dit, que tu affectais à ton pointeur une adresse qui serait invalide dès la fin de l'affectation).

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    Merci à vous !

    En fait, le compilo (VC++) me le dit bien... quand je met le niveau des warnings à 4 (il était à 3).

    Merci encore

    Cordialement
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    Comme on parle un peu optimisations, j'aurais une question supplémentaire.
    Imaginons que j'ai une formule dans laquelle apparaît plusieurs fois le produit a*b. A partir de combien de fois il devient rentable de déclarer une variable contenant le résultat a*b ?

    Pour l'instant, j'ai fait ce remplacement dès qu'un tel produit apparaît deux fois. Par exemple, avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const double stime = sqrt(_Time);
    Mais si j'écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const double& stime = sqrt(_Time);
    Ca fonctionne aussi. Le code est un peu moins lisible, mais gagne-t-on vraiment du temps à utiliser la référence ? Et est-ce que ça ne risque pas de planter ? Je pense que, pour le coup, ici la référence est inutile. Qu'en pensez-vous ?

    Merci

    Cordialement
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  7. #7
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Il me semble que c'est VS qui permet de faire ça mais que c'est pas standard... VS te permet de prolonger la vie d'une donnée temporaire jusqu'à la fin du scope où se trouve la référence.
    Mais tu devrais pas compter dessus.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    Ok merci
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/03/2014, 16h46
  2. Delete records non référencés ?
    Par BenoitM dans le forum Langage SQL
    Réponses: 9
    Dernier message: 14/12/2010, 15h29
  3. Réponses: 15
    Dernier message: 12/11/2008, 07h38
  4. [SQL 2K5] Pb : ON DELETE CASCADE : référence circulaire
    Par n00bi dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 29/05/2006, 08h48
  5. [Concept] Table de référence
    Par matlo dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 20/01/2003, 15h01

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