Programmation.c++ : problème d'acces à une méthode

Posté par Mathias Bavay (page perso, ) le 07 avril 2005
0
Bonjour !



J'ai un petit probleme... (enfin pour dire vrai, j'ai passe des heures et des heures a essayer de le resoudre sans succes): j'ai les classes suivantes:



equation {

public:

virtual double f(void);

.....

}



et inductance:equation {

public:

double f(void)

.....

}



ainsi que d'autres classes comme inductance qui heritent de "equation". Le probleme que j'ai, c'est que bizarement, quand une methode de "inductance" essaye d'appeller "f()", mon programme segfault... quand une autre classe, construite comme "inductance" appelle son propre "f()", ça marche... quand je force "inductance::f()" dans ma methode (faisant partie de "inductance"), ça marche aussi...



Donc en gros, lorsque j'appelle "f()" depuis "inductance", cela ne va pas chercher la fonction "f()" dans la classe "inductance" et plante...



De quoi cela peut-il venir ?? En sachant que les autres classes heritant de "equation" fonctionnent parfaitement.



Merci !

Mathias

> Lire le message (19 commentaires, moyenne: 1,6).  

Vous avez demandé le commentaire #557403.

Segfault ?

Posté par Obsidian () le 07/04/2005 à 18:50. (lien). Évalué à 2.

Es-tu sûr qu'il s'agisse bien d'une segfault déjà, et pas d'une division par zéro ou d'un « Abort » dù à une exception non rattrapée ?

Ensuite, elle est censée faire quoi ta fonction f ? Parce qu'une fonction mathématique sans inconnue (type void), c'est pas courant. A mon avis, le problème se situe dans le code de ta fonction.

Mets le tout en GPL et tu pourras bénéficier de l'aide de la communauté ! :-)

[ Répondre ]

  • [^]Re: Segfault ?

    Posté par platinum () le 07/04/2005 à 20:02. (lien). Évalué à 1.

    Ce qui expliquerait la différence de comportement entre deux architectures ? Peut-être. Sans l'implémentation, ça va être dur de diagnostiquer quoique ce soit ...

    [ Répondre ]

    [^]Re: Segfault ?

    Posté par Mathias Bavay (page perso, ) le 07/04/2005 à 20:10. (lien). Évalué à 2.

    Mets le tout en GPL et tu pourras bénéficier de l'aide de la communauté ! :-)
    C'est deja fait, y'a meme une page sur freshmeat : http://freshmeat.net/projects/pptools/(...)

    Bon, donc voila le code des fonctions liées a inductance::f()

    double inductance::f(void) {
    //this function is a wrapper needed by the solver

    switch(type) {
    case ParalleleWires:
    return parameters[5]-parallele_wires();
    break;
    case CoaxialLine:
    return parameters[5]-coaxial_line();
    break;
    case StripLine:
    return parameters[5]-strip_line();
    break;
    case ConvergingLine:
    return parameters[5]-converging_line();
    break;
    case Disks:
    return parameters[5]-disks();
    break;
    case RectangularCoil:
    return parameters[5]-rectangular_coil();
    break;
    case Helix:
    return parameters[5]-helix();
    break;
    }
    return (double)EXIT_FAILURE;
    }

    et un exemple de fonction appelée:

    double inductance::parallele_wires(void) {
    double length,gap,a,p;

    a=parameters[1];
    gap=parameters[2];
    length=parameters[3];
    p=sqrt(0.25*gap*gap-a*a);
    L=-MU_0/PI*length*(log(gap/a)+log(0.5-p/gap));

    return L;
    }


    Mais le pire, c'est que si je met un printf("Ici\n") au debut de la fonction "f()", rien ne s'affiche (c'est a dire que je n'entre meme pas dans la fonction !). Enfin, oui, je confirme, c'est bien d'un segfault qu'il s'agit...

    Pour ceux qui veulent jetter un oeil au source complet (dans sa version recente avec ce super bug), il est telechargeable (en l'etat) sur http://www.ivanhoe-technologies.com/products/pptools/src/pptools_0.(...)

    Juste une chose, ne pas le mettre sur un FTP publique ou autre, je n'aime pas vraiment faire des releases qui segfault des que l'on clique.... ;-) (eh oui, on a sa fiertée...)

    Ce qui provoque le bug, c'est dans l'onglet "inductance", apres avoir remplit les champs, lorsque l'on clique sur "solve", ça plante immédiatement (mais pas sur mon PPC...)

    Mathias

    [ Répondre ]

    • [^]Suggestion

      Posté par platinum () le 07/04/2005 à 20:27. (lien). Évalué à 1.

      Juste pour voir ce que cela donne : Si ta classe de base equation n'a pas à être instanciée en tant que telle, supprime le code


      double equation::f(void)
      {
      printf("using f(x) from EQUATION class... this is not normal !\n");
      return EXIT_FAILURE;
      }

      et déclare la méthode en tant que méthode virtuelle pure par

      class equation
      {
      ...
      virtual double f(void) = 0;
      ...
      };

      [ Répondre ]

      [^]Autre suggestion

      Posté par platinum () le 07/04/2005 à 20:35. (lien). Évalué à 1.

      Ecrire un destructeur pour inductance et un constructeur pour equation ...

      [ Répondre ]

      • [^]Re: Autre suggestion

        Posté par Mathias Bavay (page perso, ) le 07/04/2005 à 21:38. (lien). Évalué à 1.

        J'ai essayé de declarer f() en tant que methode purement virtuelle dans "equation", pas de changements...
        J'ai aussi essayé d'écrire un destructeur pour inductance et un constructeur pour equation, pas de changements...

        Je me dis que en effet, ce doit etre un problème de pointeur quelque part, qui se promene allegrement dans la mémoire... Hier je ne suis pas parvenu a faire fonctionner valgrind dessus, mais il faut vraiment que j'y arrive, ça pourrait m'aider a trouver ce qui ne va pas...

        On vient aussi de tester sur Solaris/Sparc, meme segfault...

        Mathias
        PS: Merci tout le monde pour vos conseils !!

        [ Répondre ]

        • [^]Re: Autre suggestion

          Posté par Obsidian () le 07/04/2005 à 22:00. (lien). Évalué à 2.

          Je pense que c'est un effet de bord. Soit la segfault paraît lors de l'appel aux sous-fonctions dans ton switch (gdb + bt roulaizent), soit c'est ton tableau de parameters qui est mal déclaré. En admettant que ta macro MAX_EQ_PARAMETERS ne puisse pas être définie pour une raison ou une autre (ex: oubli du #include idoine), ta déclaration sera alors résolue en

          double parameters[];

          Ce qui reste correct d'un point de vue syntaxique, mais qui définit un pointeur sans la mémoire qui va derrière. Cela suffirait à expliquer tes segfaults intermittentes : Lorsque tu écriras dans ce tableau, tes données n'iront pas se loger dans un endroit prévu à cet effet mais dans l'espace réservé aux variables membres que tu définis plus loin ! Donc, tu as la place de semer la pagaille un bon moment avant de planter. En fait, ton programme pourra continuer à faire le con tant qu'il ne sortira pas du segment de mémoire alloué pour ta classe entière, lequel segment aura probablement une taille alignée sur une page quelquonque. Ceci pourrait expliquer les différences de plantage en fonction des plateformes.

          [ Répondre ]