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

Langage C++ Discussion :

passer une référence en argument


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 25
    Par défaut passer une référence en argument
    Bonjour,
    j'ai une petite fonction très simple dans mon programme qui lit un vector<T>.
    Cette fonction attend un vector et s'en sert via une reférence comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int ExistBloc(const std::vector<Bloc*>& listeBloc, float posX, float posY) {
    //mon code
    }
    pour l'appeler depuis le "main" ou je déclare mon listeBloc je n'ai aucun problème.
    Seulement quand j'essaye depuis une fonction qui elle même utilise une référence vers cette liste, lors de l’exécution de ExistBloc il sort en erreur SIGSEV, comme quoi on sort de la mémoire alloué. Comme si je pointait au hasard dans la RAM la où je n'ai pas le droit de piocher.

    Je pense que j'ai raté quelque chose concernant les reférence. pouvez vous dire quoi et comme me corriger?

    Merci d'avance

  2. #2
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonsoir,
    C'est difficile de répondre avec si peu d'informations.
    Peut-être pourrais-tu mettre un peu plus de code, comme par exemple une fonction à partir de laquelle le programme plante, ou la manière dont tu remplis ton vector...

    Est-il possible que :
    • tu insères NULL dans ton vector, et que plus tard tu tentes d'accéder aux objets pointés sans vérifier la validité des pointeurs stockés ?
    • l'un des objets dont l'adresse est stockée dans le vector soit détruit sans que le pointeur associé soit retiré de ce vector ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 25
    Par défaut
    Mes excuses, je pensait que le problème ne méritait pas plus d'infos.
    alors pour le vector, il est rempli avec des add de la classe standard.
    Pour les objets je suis certain qu'il ne peut y avoir de référence sur null ou 0 car au moment de faire cet appel, je n'ai fait qu'ajouter des objets sans jamais en enlever en enlever. en vu que je parcours ma liste au moins 150 fois par frame, il me l'aurais surement dit si y'avais une fuite, et graphiquement ca sera ressentit.

    L'appel dans le game engine
    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
     
    //liste
     vector<Bloc*> listeBloc;
     Bloc cursor(10, &App, base_x_bloc, base_y_bloc);
     
    //Eléments initiaux
    float positionX = 0;
        float positionY = 0;
        listeBloc.push_back(new Bloc(1, &App, base_x_bloc + (positionX * size_x_bloc), base_y_bloc - (positionY * size_y_bloc)));
        positionX = 4;
        positionY = 0;
        listeBloc.push_back(new Bloc(2, &App, base_x_bloc + (positionX * size_x_bloc), base_y_bloc - (positionY * size_y_bloc)));
        positionX = 2;
        positionY = 0;
        listeBloc.push_back(new Bloc(2, &App, base_x_bloc + (positionX * size_x_bloc), base_y_bloc - (positionY * size_y_bloc)));
        positionX = 3;
        positionY = 0;
        listeBloc.push_back(new Bloc(1, &App, base_x_bloc + (positionX * size_x_bloc), base_y_bloc - (positionY * size_y_bloc)));
        positionX = 3;
        positionY = 1;
        listeBloc.push_back(new Bloc(4, &App, base_x_bloc + (positionX * size_x_bloc), base_y_bloc - (positionY * size_y_bloc)));
     
     
     if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Space) && !stateSpace) {
                    if (allowSwap) {
                        stateSpace = true;
                        SwapBloc(&App, listeBloc, &cursor);
                    }
                }
    Pour toutes les variables non déclaré ici, elle le sont en globales (car utilisé très souvent) et n'ont pas générés d’erreurs jusqu’à maintenant.


    dans swap bloc
    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
     
     
    bool SwapBloc(sf::RenderWindow* App, std::vector<Bloc*>& listeBloc, Bloc* cursor) {
      sf::Vector2f bufferPositionBloc;
        sf::Vector2f bufferPositionViseur;
        allowSwap = false;
        loopIncrease = false;
        allowMoveCursor = false;
        bufferPositionViseur = cursor->sprite.GetPosition();
        for (int i = 0; i < listeBloc.size(); i++) {
            bufferPositionBloc = listeBloc[i]->sprite.GetPosition();
            if ((bufferPositionBloc.x == bufferPositionViseur.x) && (bufferPositionBloc.y == bufferPositionViseur.y)) {
                SwapBlocApply(listeBloc, i, ExistBloc(listeBloc, bufferPositionViseur.x + size_x_bloc, bufferPositionViseur.y));
                i = listeBloc.size();
            } else if ((bufferPositionBloc.x == bufferPositionViseur.x + size_x_bloc) && (bufferPositionBloc.y == bufferPositionViseur.y)) {
                SwapBlocApply(listeBloc, ExistBloc(listeBloc, bufferPositionViseur.x, bufferPositionViseur.y), i);
                i = listeBloc.size();
            }
        }
        allowSwap = true;
        loopIncrease = true;
        allowMoveCursor = true;
        return true;
    allowSwap, loopIncrease et alloMoveCursor sont déclarées extern dans ce scope et défini dans mon main. jamais eu de problème avec.

    Apply swap bloc
    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
     
    bool SwapBlocApply(std::vector<Bloc*>& listeBloc, int i, int j) {
        if (j >= 0) {
            listeBloc[j]->sprite.Move(-size_x_bloc, 0);
            listeBloc[j]->tempsAvantChute = 0;
        }
        if (i >= 0) {
            listeBloc[i]->sprite.Move(size_x_bloc, 0);
            listeBloc[i]->tempsAvantChute = 0;
        }
        int k;
        k = ExistBloc(listeBloc, listeBloc[i]->sprite.GetPosition().x, (listeBloc[i]->sprite.GetPosition().y - size_y_bloc));
        if (k>-1) {
            listeBloc[k]->tempsAvantChute = paramTempsAvantChute;
        }
        k = ExistBloc(listeBloc, listeBloc[j]->sprite.GetPosition().x, (listeBloc[j]->sprite.GetPosition().y - size_y_bloc));
        if (k>-1) {
            listeBloc[k]->tempsAvantChute = paramTempsAvantChute;
        }
     
        return true;
    }
    ExistBloc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int ExistBloc(const std::vector<Bloc*>& listeBloc, float posX, float posY) {
        sf::Vector2f bufferPos(posX, posY);
        for (int i = 0; i < listeBloc.size(); i++) {
            if (listeBloc[i]->sprite.GetPosition() == bufferPos) {
                return i;
            }
        }
        return -1;
    }
    l'erreur est situé sur l'exécution de ExistBloc dans ApplySwapBloc. En déboguant il me sort l'erreur SIGSEV.
    je n'ai pas pu tester le dé-bug dans ExistBloc car elle utilisé extrêmement souvent et que netbeans, comment dire, est vraiment lent à la détente en dé-bug avec la SFML.

    si tu as besoin de plus je lâcherais tout mon code (ou presque).

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 25
    Par défaut
    Pardon a tous pour ce poste inutile, j'ai trouvé mon erreur et franchement elle est d'une imprudence fabuleuse.
    la clé est dans ApplySwapBloc, qui test l'éxistence de i et j avant d'efféctuer quoi que ce soit, mais dans les boucle suivante (qui commence par k= ....)
    je ne vérifie même pas ca, du coup dès qu'un des deux blocs n'existait pas, on utilisait un indice égal à -1.

    Problème résolu.

  5. #5
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    En médecine, on dit que plusieurs maladies peuvent avoir les mêmes symptômes.
    En programmation, c'est pareil.
    Se contenter de donner l'environnement immédiat de la détection d'une erreur revient à donner uniquement les symptômes les plus apparents.

    Parfois, la véritable cause de l'erreur peut se trouver très loin de sa détection.
    Certaines erreurs ne sont même parfois jamais détectées, jusqu'à une exécution particulière, une recompilation avec un compilateur différent ou une version différente, des modifications qui paraissent mineures...
    Et parfois, l'origine d'une erreur n'a pas de lien évident avec sa manifestation.

    Alors tu vois sûrement pourquoi il était difficile de te répondre précisément avec les informations données au début (et même impossible, en l'occurrence ).
    Quoi qu'il en soit, c'est bien que tu aies pu trouver ton erreur par toi-même.
    Et sache qu'il y a rarement des posts inutiles : même s'il n'y a pas de réponse donnée au problème initial, on apprend toujours (enfin souvent) des choses très utiles dans d'autres contextes de développement, ce qui ne peut pas faire de mal.

    Et maintenant

  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 Steph_ng8 Voir le message
    Se contenter de donner l'environnement immédiat de la détection d'une erreur revient à donner uniquement les symptômes les plus apparents.
    Pour moi, cela semble surtout poser une question de conception. Que signifient ces paramètres et quels est le contrat induit sur les objets et leur fonction ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/05/2011, 14h18
  2. [VB6]Comment puis-je passer une ComboBox en argument?
    Par Xan dans le forum VB 6 et antérieur
    Réponses: 20
    Dernier message: 26/02/2007, 15h03
  3. Réponses: 17
    Dernier message: 24/11/2006, 18h25
  4. Comment passer une fonction en argument
    Par Pades75 dans le forum Langage
    Réponses: 4
    Dernier message: 16/02/2006, 10h34
  5. Passer une fonction comme argument à une fonction
    Par Cocotier974 dans le forum Général Python
    Réponses: 4
    Dernier message: 29/06/2004, 13h41

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