Memory leak if Bitmap get's raw data from Marshal.AllocHGlobal?
I am not clear on the mechanics of native int开发者_JS百科erop.
Suppose I do the following:
IntPtr nativeArray = Marshal.AllocHGlobal(stride * height);
someNativeCallToFillRawImageData(nativeArray, width, stride, height);
return new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, nativeArray);
My allocated array then is the source of the bitmap (it works), but I am unsure if the memory for it will ever be cleared?
Alternatively, I can do the following (by changing DLLImport signature...native method is originally defined as (unsigned char *buff)):
byte[] managedArray = new byte[stride * height];
someNativeCallToFillRawImageData(managedArray, width, stride, height);
fixed (byte* ptr = managedArray)
{
return new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, new IntPtr(ptr));
}
which also works, but I am not clear on the difference exactly. I am also under the impression that the first variant is faster, due to it not having to cross managed/unmanaged boundiers.
Does a managed Bitmap object dispose of the data in Scan0, even though it was allocated by someone else? bitmap.Dispose() -> what happens to allocated memory in either managedArray or nativeArray ?
Thank you very much in advance!
If using Marshal.AllocHGlobal and the bitmap copies data from the pointer, you should free it with Marshal.FreeHGlobal. I advice you read MSDN on the BitMap constructor as to if it copies the data or just uses the pointer; if it just uses the pointer you have to wait with freeing it.
I don't think you need to allocate the memory yourself. Create an empty bitmap with the desired size, then call LockBits to access the raw pixel data:
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Rectangle rect = new Rectangle(width, height);
BitmapData data = null;
try
{
data = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
someNativeCallToFillRawImageData(data.Scan0, data.Width, data.Stride, data.Height);
}
finally
{
if (data != null)
bmp.UnlockBits(data);
}
This way, the memory is handled by the Bitmap
object, so you don't need to worry about it.
You should create a Dispose method in a class which uses unmanaged resource (nativeArray in your case) and free it using Marshal.FreeHGlobal(nativeArray )
. Something like this:
if(nativeArray != IntPtr.Zero)
Marshal.FreeHGlobal(nativeArray);
You are responsible to call created Dispose method.
精彩评论