Louis S.
Louis S.

Reputation: 11

Flood fill algorithm memory leak

I've got a memory leak somewhere. I've searched it over so many times, and it looks solid to me. I just.. can't... find it... Ok, background. This is a stack driven flood fill, and this bit of code is the only spot where I add something to the stack. There is more code, so if no one can find a memory leak, I'll post some more of it.

Here's the strangest part about this. The code works fine with just one color + line art (pictexture), but when using more than one color and using the fill bucket, I get those weird memory leaks.

 //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: I just realized I forgot to mention the weirdest part. This code works just fine until I use colors other than the starting color (blue). Once I change colors, even if it's back to blue, it still breaks.

Upvotes: 1

Views: 773

Answers (2)

Louis S.
Louis S.

Reputation: 11

I figured it out. It turns out it wasn't entirely my fault. The guy who wrote the color picker code was using a different color format than me, but the engine that we're using sometimes will implicitly convert one format to another, which is why it still worked sometimes. Very very strange. Thanks for your help though guys!

Upvotes: 0

Ed Swangren
Ed Swangren

Reputation: 124800

First, use a profiler. I have had pleasant experiences with RedGate's ANTS Memory Profiler. It is really the quickest way to get the information you need when the problem isn't obvious.

As for your code, all I noticed at first glance is that you may be creating a large number of Vector2 objects in a very short amount of time. I have no idea if this is actually causing the problem you are seeing though.

As an aside, GDI+ is slow as a dog. If you begin to notice poor performance you may want to consider using Bitmap.LockBits to get a pointer to the image data in memory and operate on that. In my experience GDI+ is simply not suitable for manipulations on images of even modest size.

Upvotes: 2

Related Questions