2012-06-14 3 views
1

J'ai une fuite de mémoire quelque part. Je l'ai cherché tant de fois, et cela me semble solide. Je ne peux pas ... le trouver ... Ok, arrière-plan. C'est un remplissage d'inondation piloté par pile, et ce bit de code est le seul endroit où j'ajoute quelque chose à la pile. Il y a plus de code, donc si personne ne peut trouver de fuite de mémoire, j'en posterai un peu plus.Algorithme de remplissage d'inondation fuite de mémoire

Voici la partie la plus étrange à ce sujet. Le code fonctionne bien avec une seule couleur + dessin au trait (pictexture), mais lorsque vous utilisez plus d'une couleur et que vous utilisez le seau de remplissage, j'obtiens ces fuites de mémoire étranges.

//descend to the floor 
      while(true) 
      { 

       if(++iterator > total) 
       { 
        Debug.Log("broke in the stupid down loop..."); 
        break; 
       } 

       //if we hit line art or a color we're not changing, break out of the loop 
       if(PicTexture.GetPixel((int)coords.x, (int)coords.y).a > .5f || 
        MyTexture.GetPixel((int)coords.x, (int)coords.y) != ColorToChange || coords.y < 0) 
       { 
        break; 
       } 


       //if we're looking right and find an open spot in our texture 
       if(reach.right && MyTexture.GetPixel((int)coords.x + 1, (int)coords.y) == ColorToChange 
        && PicTexture.GetPixel((int)coords.x + 1, (int)coords.y).a < .5f) 
       { 
        reach.right = false; //search it and stop looking right 
        if(!search.Contains(new Vector2((int)coords.x + 1, (int)coords.y))) 
         search.Push(new Vector2((int)coords.x + 1, (int)coords.y)); 
       } 
       else 
       { 
        if(MyTexture.GetPixel((int)coords.x + 1, (int)coords.y) != ColorToChange 
         || PicTexture.GetPixel((int)coords.x + 1, (int)coords.y).a >= .5f) //if theres a wall and we're not looking right 
         reach.right = true; //look for an opening to the rightq 
       } 

       //same thing for left 
       if(reach.left && MyTexture.GetPixel((int)coords.x - 1, (int)coords.y) == ColorToChange 
        && PicTexture.GetPixel((int)coords.x - 1, (int)coords.y).a < .5f) 
       { 
        reach.left = false; 
        if(!search.Contains(new Vector2((int)coords.x - 1, (int)coords.y))) 
         search.Push(new Vector2((int)coords.x - 1, (int)coords.y)); 
       } 
       else 
       { 
        if(MyTexture.GetPixel((int)coords.x - 1, (int)coords.y) != ColorToChange 
         || PicTexture.GetPixel((int)coords.x - 1, (int)coords.y).a >= .5f) 
         reach.left = true; 
       } 

       MyTexture.SetPixel((int)coords.x, (int)coords.y, BrushColor); 
       coords.y--; 
      } 

edit: Je viens de réaliser que j'ai oublié de mentionner la partie la plus étrange. Ce code fonctionne très bien jusqu'à ce que j'utilise des couleurs autres que la couleur de départ (bleu). Une fois que je change de couleur, même si elle est de retour au bleu, elle se casse toujours.

+6

Comment savez-vous que vous avez une fuite de mémoire? Quels sont les symptômes que vous ressentez? Quels outils de débogage avez-vous utilisés pour essayer d'identifier la source de la fuite? Qu'ont-ils montré? –

+0

J'utilise Debug.Log() d'Unity pour lancer des instructions de débogage afin de voir la taille de la pile de recherche, et cet itérateur pour me sortir de la boucle s'il est bloqué. Lorsque j'utilise une seule couleur, la taille de la pile ne dépasse jamais 75, et l'itérateur maintient un nombre raisonnable. J'ai cassé la boucle à 600 000 itérations et à une taille de pile de 100 afin de ne pas planter le programme. –

+0

Je ne pense pas que ce soit une fuite de mémoire mais un problème avec votre algorithme – Carsten

Répondre

2

D'abord, utilisez un profileur. J'ai eu des expériences agréables avec RedGate's ANTS Memory Profiler. C'est vraiment le moyen le plus rapide d'obtenir l'information dont vous avez besoin lorsque le problème n'est pas évident.

En ce qui concerne votre code, tout ce que j'ai remarqué à première vue, c'est que vous pouvez créer un grand nombre d'objets Vector2 en très peu de temps. Je n'ai aucune idée si cela cause le problème que vous voyez. En outre, GDI + est lente en tant que chien. Si vous commencez à remarquer des performances médiocres, vous pouvez envisager d'utiliser Bitmap.LockBits pour obtenir un pointeur vers les données d'image en mémoire et opérer dessus. Dans mon expérience, GDI + n'est tout simplement pas adapté à des manipulations sur des images de taille même modeste.

+0

Mon chien est assez rapide, mais j'ai surtout utilisé GDI + pour les graphiques vectoriels, pas pour les bitmaps. +1 pour RedGate. –

+0

Merci, même si j'utilise texture2d de Unity, et qu'il n'y a pas de fonction native Bitmap.LockBits. Voici la chose étrange. Ce code fonctionne très bien quand je le lance. Ce n'est pas avant que je change de couleur et que j'essaie d'utiliser le remplissage d'inondation qu'il commence à mal se comporter. La couleur ne devrait cependant pas avoir d'importance, car elle ne cherche que la couleur de remplacement. –

0

Je l'ai compris. Il s'avère que ce n'était pas entièrement de ma faute. Le gars qui a écrit le code du sélecteur de couleurs utilisait un format de couleur différent de moi, mais le moteur que nous utilisons parfois convertit implicitement un format en un autre, c'est pourquoi il fonctionnait parfois. Très très étrange. Merci pour votre aide si les gars!