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 :

Crash du programme à l'exécution


Sujet :

C++

  1. #1
    Membre à l'essai
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Points : 15
    Points
    15
    Par défaut Crash du programme à l'exécution
    Bonjour à tous,

    La fonction Objets_Solides doit me créer des corps solides en 3D sous PhysX. Pour cela j'utilise "softBodyDesc" de type "NxSoftBodyDesc". Mais pour pouvoir créer ces corps, "NxSoftBodyDesc::isValid()" doit retourner "true".

    Voici d'abord ma fonction:
    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
    void Objets_Solides(void)
    {
    	NxSoftBodyDesc softBodyDesc;
    	bool BodyRet2 = softBodyDesc.isValid();
    	softBodyDesc.globalPose.t = NxVec3(0.0f, 3.0f, 0.0f);
    	softBodyDesc.particleRadius = 0.2f;
    	softBodyDesc.volumeStiffness = 0.5f;
    	softBodyDesc.stretchingStiffness = 1.0f;
    	softBodyDesc.friction = 1.0f;
    	softBodyDesc.attachmentResponseCoefficient = 0.1f;
    	softBodyDesc.solverIterations = 5;
            bool BodyRet3 = softBodyDesc.isValid();
     
    ...
    }
    Le problème qui m'arrive est que pour que "softBodyDesc.isValid();" retourne true, chaque valeur attribué à un paramètre doit correspondre à ce qui est attendu. Par exemple pour "globalPose.t", est attendu un vecteur. Ce qui est le cas ici. Je sais que pour chaque paramètre, la valeur attendue est bonne.

    Ce qui cloche c'est à la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            NxSoftBodyDesc softBodyDesc;
    	bool BodyRet2 = softBodyDesc.isValid();
    Sans même avoir mis de paramètres, "BodyRet2 = false" ce qui veut dire qu'il y a un problème au niveau de la création même de "softBodyDesc".

    Voici l'image:




    Je ne sais pas si l'explication vous apparait très claire mais c'est plutôt compliqué pour moi d'expliquer pcq je ne connais pas exactement les termes adéquat pour désigner les bouts de code.

    J'espère que qqn comprendra mon problème.

    Je précise que mon code complie très bien mais crashe à l'exécution et que je suis arrivé à cet endroit après le pas à pas.

    Merci

  2. #2
    Membre à l'essai
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    En compilant pas à pas et en comparant à une fonction test d'un autre programme qui marche, je suis rentré dans la fonction "bool NxSoftBodyDesc::isValid() const", soit la fonction de validation qui doit me retourner "true".

    En comparant les deux programme, cela me donne çà:


  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Visiblement, softBodyDesc.isValid() renvoie une valeur booléenne, vraie si softBodyDesc est valide, fausse s'il ne l'est pas...

    Dés lors, il serait surement intéressant d'utiliser cette valeur avant d'essayer de travailler sur la suite, non

    Car, dans le code que tu montre, tu déclares deux variables de type booléen, mais tu n'en fais strictement rien... c'est un peu domage

    De plus, ta fonction n'étant pas destinée à renvoyer quoi que ce soit, il faudrait peut être prévoir de lever une exception si, pour une raison ou une autre, softBodyDesc venait à être invalide avant ou après l'exécution de cette fonction...

    Les deux solutions possibles sont:
    Ne rien faire du tout si softBodyDesc n'est pas valide en précondition
    Lancer une exception si softBodyDesc avant et, pourquoi pas, une autre si softBodyDesc n'est plus valide après...

    Au final, la première solution donnerait un code 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
    void Objets_Solides(void)
    {
    	NxSoftBodyDesc softBodyDesc;
            /* si ce n'est pas valide au départ, on ne fait rien :P */
    	if(softBodyDesc.isValid())
            {
    	    softBodyDesc.globalPose.t = NxVec3(0.0f, 3.0f, 0.0f);
    	    softBodyDesc.particleRadius = 0.2f;
    	    softBodyDesc.volumeStiffness = 0.5f;
    	    softBodyDesc.stretchingStiffness = 1.0f;
    	    softBodyDesc.friction = 1.0f;
    	    softBodyDesc.attachmentResponseCoefficient = 0.1f;
    	    softBodyDesc.solverIterations = 5;
                /* si softBodyDesc n'est plus valide, 
                 */
                if(!softBodyDesc.isValid())
                {
                    /* tout ce qu'il faut pour
                     * le remettre dans un état valide
                     * Mais est-ce utile, étant donné que c'est un objet
                     * propre à la fonction, qui ne sera pas renvoyé ??
                     */
                }
                ...
            }
    }
    et la deuxième pourrait prendre 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
    void Objets_Solides(void)
    {
    	NxSoftBodyDesc softBodyDesc;
    	if(!softBodyDesc.isValid())
                throw PreconditionInvalid();
            /* si on arrive ici, c'est que softBodyDesc était valide */
    	softBodyDesc.globalPose.t = NxVec3(0.0f, 3.0f, 0.0f);
    	softBodyDesc.particleRadius = 0.2f;
    	softBodyDesc.volumeStiffness = 0.5f;
    	softBodyDesc.stretchingStiffness = 1.0f;
    	softBodyDesc.friction = 1.0f;
    	softBodyDesc.attachmentResponseCoefficient = 0.1f;
    	softBodyDesc.solverIterations = 5;
            try
            {
                if(! softBodyDesc.isValid())
                    throw PostConditionInvalid();
            }
            catch(PostConditionInvalid &e)
            {
                 /* tout ce qu'il faut pour remettre softBodyDesc dans un état 
                  * valide
                  */
                 /* on lève une exception disant qu'on n'a pas modifié l'objet */
                 throw SolidObjectNotDone();
     
            }
     
    ...
    }
    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

  4. #4
    Membre à l'essai
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    J'ai regardé ce qui merdait avec mon "softBodyMesh", j'ai donc repris mon pas à pas à partir de là:


    -> NxSoftBodyDesc softBodyDesc;
    bool BodyRet2 = softBodyDesc.isValid();


    Donc "NxSoftBodyDesc softBodyDesc;" me fait rentrer là:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        NX_INLINE NxSoftBodyDesc::NxSoftBodyDesc()
        {
    	    setToDefault();
        }

    Et "setToDefault();" me fait arrviver là:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    NX_INLINE void NxSoftBodyDesc::setToDefault()
        {
    	softBodyMesh = NULL;
    	globalPose.id();
    	particleRadius = 0.1f;
    	density = 1.0f;
        ...
       }

    Donc comme on peut le voir "softBodyMesh" est bien mis à NULL et donc je ne peux pas avoir:
    if(!softBodyMesh) return false;

    En fait, ça me donne cà:



    et çà:




    Pour moi, tout le problème vient de là mais je ne sais pas comment le résoudre.

    Y-a-t-il qqn qui puisse m'aider?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par MaTtaW Voir le message
    J'ai regardé ce qui merdait avec mon "softBodyMesh", j'ai donc repris mon pas à pas à partir de là:


    -> NxSoftBodyDesc softBodyDesc;
    bool BodyRet2 = softBodyDesc.isValid();


    Donc "NxSoftBodyDesc softBodyDesc;" me fait rentrer là:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        NX_INLINE NxSoftBodyDesc::NxSoftBodyDesc()
        {
    	    setToDefault();
        }

    Et "setToDefault();" me fait arrviver là:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    NX_INLINE void NxSoftBodyDesc::setToDefault()
        {
    	softBodyMesh = NULL;
    	globalPose.id();
    	particleRadius = 0.1f;
    	density = 1.0f;
        ...
       }

    Donc comme on peut le voir "softBodyMesh" est bien mis à NULL et donc je ne peux pas avoir:
    if(!softBodyMesh) return false;
    Si, justement, un pointeur NULL est évalué à false...

    Autrement dit, if(!softBodyMesh) sera évalué à vrai si softBodyMesh est nul, ce qui provoque le renvoi de false parce que !false == true

    Ce code correspond en fait à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(softBodyMesh==NULL) return false;
    [EDIT]Moralité, soit tu dois déclarer ta variable de type NxSoftBodyDesc en utilisant un autre constructeur (qui prend un argument qu'il te faut déterminer), soit, après avoir déclaré ta variable, mais avant de tester la validité, tu dois veiller à appeler une fonction d'intialisation...

    Quoi qu'il en soit, j'ai l'impression qu'il te manquera la variable qui te permettra d'initialiser softBodyMesh dans ta fonction
    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
    Membre à l'essai
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Ok, (!softBodyMesh) doit me retourner vrai, pour cela softBodyMesh doit être NULL.

    Mais en passant par la fonction "setToDefault()", il est bien passé NULL. Non?

    EDIT:

    Ah non, attend, justement, Il est mis à NULL par défaut mais ne doit pas être NULL pour que "isValid" renvoir True !

    EDIT:

    Mais dans ce cas, par rapport à mes imprime-écrans, j'en conclue quoi?

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Soyons clair, le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(!softBodyMesh) return false;
    correspond à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if(softBodyMesh ==NULL)
    {
        return false;
    }
    else
    {
        /* ne fait rien */
    }
    Donc, pour que isValid() puisse finir par renvoyer true, il faut... qu'il passe par la partie else du test (celle qui ne fait rien)...

    Et, pour que cela arrive, il faut... que softBodyMesh représente une adresse valide.

    C'est ce qui me fait dire qu'il faut pouvoir donner quelque chose à la classe NxSoftBodyDesc pour qu'elle puisse initialiser correctement ce pointeur.

    Cela est susceptible de se faire de deux manières:
    • Soit par un mutateur sur softBodyMesh (du genre de setSoftBodyMesh(un truc du type adéquat) )
    • Soit en invoquant un autre constructeur que le constructeur par défaut.

      Vérifie donc les autres constructeurs pour voir si tu n'a pas, justement, un constructeur qui prendrait:
      • Soit une variable du type adéquat pour générer softBodyMesh
      • Soit une variable du type adéquat pour générer softBodyMesh, un NxVec3, 5 réels et 1 entier... (pour ce que j'ai pu déterminer au départ de ton code )
    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

  8. #8
    Membre à l'essai
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Ok je vais zieuter tout ça pour voir exactement quoi faire et tiens au courant.

    Merci bcp pour le coup de main.

  9. #9
    Membre à l'essai
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Points : 15
    Points
    15
    Par défaut
    Salut,

    j'ai réussi à résoudre mon problème à l'aide de tes conseils.


    Comme tu disais, le booléen retourne false parceque SoftBodyMesh est NULL, donc ne contient pas d'adresse valide. Il faut donc regardé comment il est créé, par quelle fonction.


    En regardant les différentes formes de déclaration de "softBodyMesh", je vois que dans le fichier MySoftBody.cpp, à la fonction "bool MySoftBody::cookMesh(NxSoftBodyMeshDesc& desc)", il y a la ligne:

    mSoftBodyMesh = mScene->getPhysicsSDK().createSoftBodyMesh(rb);

    qui utilise la fonction "createSoftBodyMesh".


    J'ai donc comparé mon fichier MySoftBody.cpp avec celui utilisé par le programme test qui marche, et je vois que dans la fonction:

    "void MySoftBody::init(NxScene *scene, NxSoftBodyDesc &desc, NxSoftBodyMeshDesc &meshDesc, ObjMesh *surfaceMesh)"

    là où il y a la ligne "mSoftBody = scene->createSoftBody(desc);", n'apparait pas ou a été effacé:

    if(meshDesc.isValid())
    {
    NxInitCooking();
    cookMesh(meshDesc);
    NxCloseCooking();
    }


    C'est notamment grace à "cookMesh(meshDesc);" qu'est créé "softBodyMesh".

    En créant "softBodyMesh", on lui donne une adresse valide, il n'est donc plus NULL.

    A partir de là, la fonction "isValid()" peut retourner true.
    On peut ainsi faire l'initialisation et donc la création du SoftBody.


    Donc problème réglé, je peux continuer mon boulot.

    Merci pour tout.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/04/2007, 11h30
  2. Réponses: 8
    Dernier message: 18/03/2007, 02h28
  3. Remonter une valeur d'un programme VB exécuté d'une fenêtre DOS
    Par Coin dans le forum VB 6 et antérieur
    Réponses: 31
    Dernier message: 12/03/2007, 17h50
  4. Réponses: 3
    Dernier message: 14/12/2006, 11h46
  5. Intercepter un crash du programme ?
    Par Rudyweb dans le forum MFC
    Réponses: 3
    Dernier message: 03/03/2005, 13h58

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