Forum de la communauté SFML

Aide => Général => Discussion démarrée par: Ryohai le Mai 01, 2012, 12:08:53 am

Titre: Problème "segfault"
Posté par: Ryohai le Mai 01, 2012, 12:08:53 am
Salut a tous, je post car j'ai un soucis de gestion de mémoire..

Un petit exemple de code:
                for(int i = 0; i < fireboss.size(); i++)
                {
                    if(fireboss[i]->IsDead())
                    {
                        delete fireboss[i];
                        fireboss[i] = 0;
                        fireboss.erase(fireboss.begin() + i);
                        i--;
                    }
                    else
                    {
                    fireboss[i]->Movefire(5);
                    }
                }

Ou encore:
        for(int i = 0; i < rockets.size(); i++)
        {
            AABB rocketAABB(rockets[i]->GetPosition().x, rockets[i]->GetPosition().y, rockets[i]->Gettaile().x, rockets[i]->Gettaile().y);
            for(int j = 0; j < asteroids.size(); j++)
            {
                AABB asteroidAABB(asteroids[j]->GetPosition().x, asteroids[j]->GetPosition().y, asteroids[j]->Gettaile().x, asteroids[j]->Gettaile().y);
                if(Collision::CollisionAABB(rocketAABB, asteroidAABB))
                {
                collisionrocket = true;
                indice = j;
                break;
                indice = i;
                break;
                }
            }
        }

Si quelqu'un pourrais m'expliquer comment faire, ça serais sympa..
Merci d'avance
Titre: Re : Problème "segfault"
Posté par: Koryushin le Mai 01, 2012, 12:32:10 am
Le problème c'est qu'il y a pas beaucoup d'explication ni de code pour pouvoir t'aider.  :-\
je présume que fireboss est un std::vector<...> ?  ;)

Pourquoi ne pas passer directement par les itérateurs plutôt que d'utiliser des indices (si c'est bien un std::vector)?

Pour le premier problème je dirais que ca vient de la ligne i-- qu'il faut supprimer.
Premier tour de boucle i vaut 0 donc après le i-- il vaut -1. Au deuxième tour il vaudra donc 0 or fireboss[0] aura été supprimé dans le tour de boucle précédent. Enfin si je dit pas de bêtises.

personnellement  je préfère cette écriture: (question de goût)  ;D
std::vector<...>::iterator it; // J'ai mis des ... entre les chevrons car je sais pas quel type d'objet tu utilises
                               // Mais a vu de nez c'est un pointeur vers un objet
for(it = fireboss.begin(); it != fireboss.end(); ++it)
{
        if((*it)->IsDead())
        {
                delete (*it);
                (*it) = NULL;
                fireboss.erase(it);
        }
        else
        {
                (*it)->Movefire(5);
        }
}

 

Pour le 2 eme bout de code pareil y a pas assez d'elements pour dire ce qui va pas.
Titre: Re : Problème "segfault"
Posté par: lezebulon le Mai 01, 2012, 12:39:03 am
Koryushin c'est le contraire, son code pour itérer sur un vector est bon et pas le tien.
Le sien :
tu vires un élément et tu te replaces au même indice, mais maintenant tu es sur l'élément d'après.
Le tien:
Tu invalides l'itérateur quand tu appelles erase(), donc le ++it d'après va planter. Faut faire:
if((*it)->IsDead())
        {
                delete (*it);
                //(*it) = NULL; <-- inutile
                fireboss.erase(it++);
        }
        else
        {
                (*it)->Movefire(5);
                  ++it
        }
et pas de ++it dans la boucle
Titre: Re : Problème "segfault"
Posté par: Koryushin le Mai 01, 2012, 12:53:35 am
Oui effectivement, avec la fatigue j'ai pas fait gaffe à mon code.
std::vector<...>::iterator it; // J'ai mis des ... entre les chevrons car je sais pas quel type d'objet tu utilises
                               // Mais a vu de nez c'est un pointeur vers un objet
for(it = fireboss.begin(); it != fireboss.end();)
{
        if((*it)->IsDead())
        {
                delete (*it);
                it = fireboss.erase(it);
        }
        else
        {
                (*it)->Movefire(5);
                ++it;
        }

 

Le code avec les itérateurs, complètement corrigé grâce à lezebulon
Titre: Re : Problème "segfault"
Posté par: Ryohai le Mai 01, 2012, 10:09:36 am
Merci pour vos réponse  :)

Du coup je dois modifier mon bout de code pour les collisions non ?

Code:
        for(int i = 0; i < fireboss.size(); i++)
        {
            AABB vaisseauAABB(Vais.GetPosition().x, Vais.GetPosition().y, Vais.Gettaile().x, Vais.Gettaile().y);
                AABB fireAABB(fireboss[i]->GetPosition().x, fireboss[i]->GetPosition().y, fireboss[i]->Gettaile().x, fireboss[i]->Gettaile().y);
                if(Collision::CollisionAABB(fireAABB, vaisseauAABB))
                {
                collisionFire = true;
                indice = i;
                break;
                }
        }
Titre: Re : Problème "segfault"
Posté par: lezebulon le Mai 03, 2012, 11:49:09 pm
Je vois pas de prob pour ton code de collision, à part que vaisseauAABB tu peux le sortir de la boucle
Titre: Re : Problème "segfault"
Posté par: Ryohai le Mai 04, 2012, 12:18:21 am
Je demande ça car code::block me dis toujours ça --> "\vaisseaurevenche\main.cpp|344|warning: comparison between signed and unsigned integer expressions|" Et que je sais pas comment faire :/
Titre: Re : Re : Problème "segfault"
Posté par: Lo-X le Mai 04, 2012, 12:44:51 am
Je demande ça car code::block me dis toujours ça --> "\vaisseaurevenche\main.cpp|344|warning: comparison between signed and unsigned integer expressions|" Et que je sais pas comment faire :/

Comme je te l'ai déjà dis, tu compares un int et un unsigned int.
Un int est un nombre entre -2 147 483 648 et 2 147 483 647 (si mes souvenirs sont bons :p )
unsigned = non signé = 0 à 4 294 967 295
(en 32bits pour les deux cas)

std::vector::size() retourne un unsigned int (normal la taille ne eut pas être négative), ton "i" est un int. Si tu ne veux plus le warning, défini ton i comme unsigned int.
Titre: Re : Problème "segfault"
Posté par: Ryohai le Mai 04, 2012, 01:49:05 am
Ah d'accord, j'avais pas fais attention desolé. En tout cas merci a vous de m'avoir aider :-)