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 :

Gestion de mémoire (core dumped si vite ?)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut Gestion de mémoire (core dumped si vite ?)
    Bonjour, je développe en ce moment, un simulateur de vie. Une version stable est sortie il y a quelque temps et j'ai constaté qu'au bout d'un certains temps (2minutes et 3000 entités fabriqués sachant que sur un ancien projet et pour un code similaire [utilisant la gestion de mémoire], je pouvais créer 100 000 "objets" facilement et sans problème), la machine s'en balle et les reproductions deviennent incontrôlables. Aussi, dans l'objectif de résoudre ce problème, je poste ici la fonction permettant de gérer les reproductions pour savoir ce qui ne va pas à l'intérieur.

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    int createNewLife(SDL_Surface* screen, life **pp_humans, world *aWorld, signed int i, signed int i2, int sex, int pMouseX, int pMouseY, int stat)
    {
        int c = 254, p = L_H_CASE*L_H_CASE, s = 5;
        int r = 0, g = 0, b = 0;
        int error = 0, n = 0;
        int x = 0, y = 0;
     
        if(*pp_humans != NULL || stat == 1) /* stat = 1 signifie que la creation debute et que *pp_humans == NULL */
        {
            SDL_Rect position;
     
            if(aWorld != NULL)
            {
                n = aWorld->nbr_of_lifes + 1; /* Comme on cree un nouvel humain, on incremente */
     
                life *temp_humans = NULL;
                life *temp_humans2 = *pp_humans;
     
                temp_humans = realloc(*pp_humans, n*sizeof *temp_humans);
     
                if(temp_humans != NULL)
                {
                    *pp_humans = temp_humans;
                    (temp_humans+n-1)->surface = SDL_CreateRGBSurface(SDL_HWSURFACE, L_H_CASE, L_H_CASE, 32, 0, 0, 0, 0);
                    (temp_humans+n-1)->time_life = TIME_OF_LIFE;
                    (temp_humans+n-1)->activate = 0;
     
                    r = rand() % (c+1);
                    g = rand() % (c+1);
                    b = rand() % (c+1);
     
                    if(pMouseX != -1 && pMouseX != -1) /* Si l'ordre de creation de vie vient de l'utilisateur */
                    {
                        x = pMouseX;
                        y = pMouseY;
                    }
                    else /* Sinon on genere une position au hasard avec une contraite */
                    {
                        x = rand() % (p+1);
                        y = rand() % (p+1);
                    }
     
                    if(i != -1 && i2 != -1) /* Si ce n'est pas la creation de depart */
                    {
                        sex = rand() % (s+1);
     
                        if(sex >= 2)
                        {
                            (temp_humans+n-1)->sex = (temp_humans2+i)->sex; /* Le nouvel humain prend le sexe du geniteur 1 */
                        }
                        else
                        {
                            (temp_humans+n-1)->sex = (temp_humans2+i2)->sex; /* Il prend celui du geniteur 2 */
                        }
     
                        (temp_humans+n-1)->color.r = mix_color((temp_humans2+i)->color.r, (temp_humans2+i2)->color.r);
                        (temp_humans+n-1)->color.g = mix_color((temp_humans2+i)->color.g, (temp_humans2+i2)->color.g);
                        (temp_humans+n-1)->color.b = mix_color((temp_humans2+i)->color.b, (temp_humans2+i2)->color.b);
     
                        (temp_humans+n-1)->parents.id_person1 = (temp_humans2+i)->id; /* L'identite' de son pere */
                        (temp_humans+n-1)->parents.id_person2 = (temp_humans2+i2)->id; /* Celle de sa mere */
                    }
                    else /* Si c'est la creation de depart alors on genere tout ale'atoirement */
                    {
                        while (r == 0 && g == 0 && b == 0)
                        {
                            r = rand() % (c+1);
                            g = rand() % (c+1);
                            b = rand() % (c+1);
                        }
     
                        (temp_humans+n-1)->color.r = r;
                        (temp_humans+n-1)->color.g = g;
                        (temp_humans+n-1)->color.b = b;
     
                        (temp_humans+n-1)->sex = sex;
                    }
     
                    (temp_humans+n-1)->position.x = x;
                    position.x = x;
                    (temp_humans+n-1)->position.y = y;
                    position.y = y;
     
                    (temp_humans+n-1)->id = n; /* Son identite' */
     
                    SDL_FillRect((temp_humans+n-1)->surface, NULL, SDL_MapRGB(screen->format, r, g, b));
                    SDL_BlitSurface((temp_humans+n-1)->surface, NULL, screen, &position);
     
                    aWorld->nbr_of_lifes = n;
                    aWorld->nbr_of_lifes_now++;
                }
                else
                {
                    error = 3;
                }
            }
            else
            {
                error = 2;
            }
        }
        else
        {
            error = 1;
        }
     
        return error;
    }
    Car je suis quasi certain que le problème est là.

    J'ai déjà posté il y a longtemps un code qui fait la même chose mais en plus simple. En réalité, j'avais isolé la fonction (c.f au dessus) dans un nouveau projet. Aujourd'hui cette même fonction à grossie et je n'ai pas l'envie de reprendre le projet "d'isolement de la fonction" (le résultat de ce projet était positif), ainsi, je poste directement la fonction qui se trouve dans le code source de mon projet "Life", si vous voyez SDL, c'est la librairie que j'utilise. Pas de soucis, le code est bien écrit en C et il n'y a qu'une fois ou deux que l'on rencontre le mot SDL donc il suffit juste de connaître le C pour m'aider.
    Ce n'est pas un projet pour une quelconque université ou IUT (j'ai 16 ans) mais simplement pour moi et la communauté.

    Merci d'avance

  2. #2
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Tu ne peux pas créer une fonction de test qui appelle par exemple 100000fois cette fonction où tu crois qu'il y a un bug avec différents paramètres et essayer de voir à quel moment cela plante.

    désolé de n'avoir d'autres techniques plus efficace que de lire le code source et le comprendre pour retrouver l'erreur qui s'y est caché..

    PS : sinon j'ai téléchargé life mais cela fait quoi mise à part créer des rectangles un peu partout, cela crée un rectangle puis au bout d'un moment il est détruit ?!?

    bon courage

  3. #3
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Ouai, je vais essayer de faire cela (c'était une question ? Il n'y avait pas de "?" )
    Sinon, il y a la doc pour Life Mais en gros, c'est des carrés qui se reproduisent et qui meurent (dans la version 1.0 si je puis dire) mais dans la futur version, l'utilisateur pourra lui même cliquer à un endroit de l'écran et faire apparaître une entité.

    C'est partie pour une folle nuit de tests ! Let's go

  4. #4
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Alors voilà, j'ai du nouveau : Je résume en gros mes tests :

    Il y a encore quelques minutes, au bout de 2min, mon programme ne pouvait plus gérer les reproductions. Je viens de me rendre compte d'un truc tout bête:

    Lors de la reproduction entre entité1 et entité2, l'entité 3 se trouvait à la position 0, 0 et cela se déroule de la même façon lors de chaque reproduction or si l'on a un nombre croissant de reproductions en un temps très court, on aura X entités en position {0;0} donc emballement du système et explosion de ce dernier (enfin pour l'explosion je sais pas encore, mon pc est encore froid). Ainsi, j'ai modifié et permis à l'entité3 (bébé) d'arriver dans une position {x;y} inconnu (c'est moins réaliste mais c'est par rapport à une contrainte physique).

    Une autre question :

    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
     
    int verif_position_generation(int i, int i2, life **pp_humans)
    {
        life *temp_humans = NULL;
        int rslt = SUCCESS+4;
     
        if(*pp_humans != NULL)
        {
            temp_humans = *pp_humans;
     
            if((temp_humans+i)->position.x == (temp_humans+i2)->position.x)
            {
                if((temp_humans+i)->position.y == (temp_humans+i2)->position.y)
                {
                    if((temp_humans+i)->parents.id_person1 == -1 || (temp_humans+i)->parents.id_person1 != (temp_humans+i2)->id)
                    {
                        if((temp_humans+i)->parents.id_person2 == -1 || (temp_humans+i)->parents.id_person2 != (temp_humans+i2)->id)
                        {
                            if((temp_humans+i)->sex != (temp_humans+i2)->sex)
                            {
                                rslt = SUCCESS;
                            }
                        }
                    }
                }
            }
        }
     
        return rslt;
    }
    Voilà mon algorithme (shame on me, ce n'est pas un vrai algo ) de verification de position entre une entité1 et une entité[X] (en parcourant un tableau).

    Cela peut il affecter mon programme ? Je veux dire, si j'ai 2 000 (2*10^3) entités et que seul la position {x;y} de l'entité 1999 est la même que l'entité1, cela peut il engendrer des bugs (arret du prog, core dumped... ?) car je parcours TOUT mon tableau dans la boucle principal (je n'utilise pas de thread).

    Merci d'avance

  5. #5
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Tu veux dire que tu fais un truc de ce style là?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for (i = 0; i < nb_humains; i++)
    {
      for (j = i+1; j < nb_humains; j++)
      {
         if (verif_position_generation(i, j, pp_human) == SUCCESS)
         {
            ...
         }
      }
    }
    Si c'est ça, alors pour éviter qu'il y ait trop de vérifications (avec 2000 individus, ca fait à peu près 2 000 000 de vérifications si je suis pas trop nul en maths), tu peux découper ta scène en quadrillage, et après vérifier case par case les éléments qu'il y a dedans. (notamment il y a le tuto de fearyourself pour le pong en c++ qui gère la collision de 3000 balles, même si c'est en c++)
    Sinon, en regardant sur internet ("test de collision"), tu trouveras surement plein d'algos rapides.
    Tu peux passer alors de 2 000 000 de vérifications à 8000 par exemple.
    __________________________________
    Petite remarque (petite optimisation):
    Dans ta fonction verif, tu peux faire ça:
    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
    int verif_position_generation(int i, int i2, life *pp_humans)
    {
        life *temp_humans = NULL;
        int rslt = SUCCESS+4;
     
        if(*pp_humans != NULL)
        {
            temp_humans_i = pp_humans+i;
            temp_humans_i2 = pp_humans+i2;
     
            if((temp_humans_i)->position.x == (temp_humans_i2)->position.x)
            {
                if((temp_humans_i)->position.y == (temp_humans_i2)->position.y)
                {
                    if((temp_humans_i)->parents.id_person1 == -1 || (temp_humans_i)->parents.id_person1 != (temp_humans_i2)->id)
                    {
                        if((temp_humans_i)->parents.id_person2 == -1 || (temp_humans_i)->parents.id_person2 != (temp_humans_i2)->id)
                        {
                            if((temp_humans_i)->sex != (temp_humans_i2)->sex)
                            {
                                rslt = SUCCESS;
                            }
                        }
                    }
                }
            }
        }
     
        return rslt;
    }
    Par exemple, tu n'as pas besoin d'un double pointeur (enfin peut-être, je ne fais que supposer ), car lorsque tu passes un pointeur en argument à une fonction (aussi bien qu'un objet), l'utilisateur ne peut pas le modifier directement. De plus, au lieu de faire à chaque fois (temp_humans+i), j'ai créé une variable temp_humans_i, même chose avec temp_humans+i2. Ca évite des additions superflues.
    Ensuite, lors de tes tests, si ce n'est déjà fait, mets les tests qui sont les plus susceptibles d'éliminer les concurrents en premier, comme ça ça t'évite les autres test après (mais apparement tu le fais )

    Voilà, c'est vraiment juste des mini-optimisations

  6. #6
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    u veux dire que tu fais un truc de ce style là?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for (i = 0; i < nb_humains; i++)
    {
      for (j = i+1; j < nb_humains; j++)
      {
         if (verif_position_generation(i, j, pp_human) == SUCCESS)
         {
            ...
         }
      }
    }
    Ouai dans le genre. (Je n'aime pas utiliser les "cases")

    Merci, je vais me renseigner, comme c'était du C++, j'avais pas trop voulu voir ca.
    __________________________________
    Petite remarque (petite optimisation):

    C'est sympa mais non logique selon moi car pour une entité I il faut que je parcours le tableau et votre optimisation ne fait que vérifier la position entre une entité I et une entité I+1;
    _________________________________
    Est ce que mon code de verification de position peut engendrer un core dumped ? (tiens, il me vient une idée, je vais le tester en le bouclant 10 000 fois sur un projet isolé, je n'y avais pas pensé )
    _________________________________
    Merci.

Discussions similaires

  1. [JNI]Fuite mémoire/ core dumped JVM
    Par kinder29 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 02/09/2008, 16h31
  2. Comment générer un core dump en c
    Par gege2061 dans le forum Linux
    Réponses: 3
    Dernier message: 12/11/2006, 15h33
  3. Gestion de Mémoire Java
    Par lebulls dans le forum Langage
    Réponses: 5
    Dernier message: 18/07/2006, 10h35
  4. Problème de Core Dumped !
    Par KneXtasY dans le forum C
    Réponses: 8
    Dernier message: 24/12/2005, 13h11
  5. Segmentation fault (core dumped)
    Par Battosaiii dans le forum C
    Réponses: 13
    Dernier message: 25/11/2005, 18h36

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