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 :

Liste chainée & boucle infinie


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 335
    Par défaut Liste chainée & boucle infinie
    Bonjour,

    Je dois faire un projet en C pour mon école d'ingénieur. Je programme une sorte de shoot-em up. Or, lors de mes tests de collisions j'ai de temps en temps un fonctionnement innatendu de ma fonction,c'est à dire qu'elle se transforeme en boucle infinie...

    J'utilise le code suivant :

    (list représente une liste simplement chainée).

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    void Update_CheckCollision(PlayData* Data)
    {
        list PlanesPrev = NULL;
        list MissilePrev = NULL;
        list MissileCurr= Data->missiles;
        list PlanesCurr = Data->planes;
        list tmp;
     
        while (MissileCurr!=NULL)
        {
            list PlanesCurr = Data->planes;
     
            while (PlanesCurr != NULL)
            {
                if(((Missile*)MissileCurr->data)->position.x > ((Plane*)PlanesCurr->data)->position.x - ((Plane*)PlanesCurr->data)->size.x/2  &&
                    ((Missile*)MissileCurr->data)->position.x < ((Plane*)PlanesCurr->data)->position.x + ((Plane*)PlanesCurr->data)->size.x/2  &&
                    ((Missile*)MissileCurr->data)->position.y > ((Plane*)PlanesCurr->data)->position.y - ((Plane*)PlanesCurr->data)->size.y/2  &&
                    ((Missile*)MissileCurr->data)->position.y < ((Plane*)PlanesCurr->data)->position.y + ((Plane*)PlanesCurr->data)->size.y/2)
                {
                    if(MissilePrev == NULL)
                    {
                        tmp = Data->missiles;
                        if (Data->missiles->next != NULL)
                            Data->missiles = Data->missiles->next;
                        MissileCurr = Data->missiles;
                        free(tmp);
                    }
                    else
                    {
                        MissilePrev->next = MissileCurr->next;
                        free(MissileCurr);
                        MissileCurr = MissilePrev;
                    }
                    if (--(((Plane*)PlanesCurr->data)->life) <= 0)
                    {
                        if (PlanesPrev == NULL)
                            {
                            tmp = Data->planes;
                            if (Data->planes->next != NULL)
                                    Data->planes = Data->planes->next;
                                PlanesCurr = Data->planes;
                                free(tmp);
                            }
                        else
                        {
                            PlanesPrev->next = PlanesCurr->next;
                            free(PlanesCurr);
                            PlanesCurr = PlanesPrev;
                        }
                    }
                } 
                //printf("%i\t%i\n", PlanesCurr, PlanesCurr->next);
                PlanesPrev = PlanesCurr;
                PlanesCurr = PlanesCurr->next;
            }
            MissilePrev = MissileCurr;
            MissileCurr = MissileCurr->next;
        }
        printf("Done");
    }
    Si je décommente le printf (printf("%i\t%i\n", PlanesCurr, PlanesCurr->next), j'obtient :

    Nom : Values.png
Affichages : 1814
Taille : 12,4 Ko

    Je me retrouve avec des liste pseudo-circulaires alors que ce sont des listes génériques simples.

    Si vous avez une idée d'où pourrait venir mon problème, je suis tout ouïe

    Merci d'avance de votre aide !

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    Une première erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    list PlanesCurr = Data->planes;
        list tmp;
     
        while (MissileCurr!=NULL)
        {
            list PlanesCurr = Data->planes;
    Dans un tel cas, le compilateur va faire deux variables PlanesCurr différente et va choisir la variable la plus "proche" du bloc actuel. Mais du coup, lorsque vous sortez du while, il réutilise l'autre variable et donc, utilise une autre valeur.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre émérite
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 335
    Par défaut
    Oh, bien vu !

    J'ai changé ça mais l'erreur persiste. A un moment qui me semble aléatoire, la boucle devient infinie (un truc du genre Plane->suivant = UnPlaneQueJ'aiDéjàPassé). Mais comme il n'y a pas moyen d'y aller au déboggeur, et comme cette fonction tourne très rapidement, je ne peux pas non plus y aller au printf.

    Si tu as des idées...

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par défaut
    Mais comme il n'y a pas moyen d'y aller au déboggeur
    Pourquoi donc ?

    Y a t-il d'autres fonctions qui affectent la liste chainée ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre émérite
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 335
    Par défaut
    Mais comme il n'y a pas moyen d'y aller au déboggeur
    Pourquoi donc ?
    Parce que ma fonction peut marcher correctement pendant plusieurs milliers de tours avant que le problème se produise. Et comme il n'y a pas de plantage effectif, simplement cette fonction qui se transforme en boucle infinie, je ne crois pas que le déboggeur de Code Blocks puisse m'aider.

    Oui, j'ai d'autres fonctions qui touchent mes listes chaînées , mais je ne pense pas qu'elles soient responsables de ce bug puisque si je rajoute en début de fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (PlanesCurr!=NULL)
        {
            printf("[%i;%i]",PlanesCurr,PlanesCurr->data);
            PlanesCurr = PlanesCurr->next;
        }
        while (MissileCurr!=NULL)
        {
            printf("{%i;%i}",MissileCurr,MissileCurr->data);
            MissileCurr = MissileCurr->next;
        }
    je n'ai pas de boucle infinie affichée à l'écran. Ça prouve que mon erreur se trouve à l'intérieur de ma fonction.

    Au sinon il y a peut être moyen d'implémenter différemment cette méthode. En effet, ça pourrait permettre de contourner mon problème, et j'ai conscience qu'une gestion de collision qui fait absolument tout les tests possible peut vite devenir lourde. Et puis quand un problème persiste après deux jours, il vaut peut-être mieux le contourner...

    Merci de votre aide.

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par défaut
    Le débogueur peut aider, car lorsque vous voyez la boucle infinie, vous pouvez le mettre en pause et il s'arrêtera et vous permettra de déboguer, dans la boucle infinie.

    Les autres fonctions peuvent créer la boucle infinies, en modifiant la liste chainées et en provoquant le bouclage. Je pense notamment à la destruction/suppression d'un élément, qui causerai ce type de bouclage.
    D'ailleurs, vous devriez faire des fonctions de base pour la gestion de la liste : création/ajout/suppression/destruction.
    Cette partie là est obscure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if(MissilePrev == NULL)
                    {
                        tmp = Data->missiles;
                        if (Data->missiles->next != NULL)
                            Data->missiles = Data->missiles->next;
                        MissileCurr = Data->missiles;
                        free(tmp);
                    }
    Pouvez-vous m'expliquer ce que vous avez voulu faire ... et pourquoi elle est nécessaire ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

Discussions similaires

  1. Boucle infinie lors d'un parcours d'une liste
    Par cocosql dans le forum Prolog
    Réponses: 3
    Dernier message: 16/01/2009, 07h23
  2. Réponses: 15
    Dernier message: 24/05/2005, 08h34
  3. [C#] Comment eviter les boucles infinies ?
    Par Thomas Lebrun dans le forum C#
    Réponses: 12
    Dernier message: 09/06/2004, 00h04
  4. Trie liste chaine
    Par Congru dans le forum C
    Réponses: 2
    Dernier message: 30/03/2004, 19h05
  5. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25

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