Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will disposable object clone cause memory leak in C#?

Check this code:

.. class someclass : IDisposable{
    private Bitmap imageObject;
    public void ImageCrop(int X, int Y, int W, int H)
    {
        imageObject = imageObject.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat);
    }
    public void Dispose()
    {
        imageObject.Dispose();
    }
}

Bitmap is ICloneable, IDisposable in C#.

Too avoid memory leak, for Disposable object, normally use using, then the object will be disposed by system automatically no matter how wrong your code went.

In my sample, I cannot use using since I do not want to dispose the object, I need it later (the whole class will dispose itself since its IDisposable as well.

My question is: I have a imageObject object, then I use it Clone() method clone a new object and give it to the old object variable. Will this cause one (either the cloned or the original) object go nowhere and never get disposed, a memory leak.

[EDIT]

Seems most opinions are Clone cause additional object, the old one should be Dispose()

Here is the new code:

    public void ImageCrop(int X, int Y, int W, int H)
    {
            // We have 1 object: imageObject
            using (Bitmap croppedImage = imageObject.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat))
            {
                    // We have 2 objects: imageObject and croppedImage
                    imageObject.Dispose(); // kill one, only croppedImage left
                    imageObject = new Bitmap(croppedImage); // create one, now 2 objects again
            } // the using() will kill the croppedImage after this
            // We have 1 object: imageObject
    }

and it should be proper Dispose the resources.

like image 392
Eric Yin Avatar asked Jan 08 '12 22:01

Eric Yin


2 Answers

using just calls Dispose in a finally block.
As long as you call Dispose somewhere in all code paths, you're fine.

If you don't call Dispose, the GC will eventually dispose it for you, but this can lead to resource contention.

In this particular case, you should probably dispose the original after cloning it, since it looks like you never use it again.

like image 106
SLaks Avatar answered Nov 19 '22 05:11

SLaks


I can't say for sure, but if you are afraid it might, why not clone the image to a new variable, dispose the original, and then reassign:

public bool ImageCrop(int X, int Y, int W, int H)
{     
    Bitmap croppedImage = imageObject.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat);
    imageObject.Dispose();
    imageObject = new Bitmap(croppedImage);
    croppedImage.Dispose();
}
like image 2
scott.korin Avatar answered Nov 19 '22 07:11

scott.korin