I'm using locked bitmaps a lot recently, and I keep getting "attempted to access invalid memory" errors. This is mostly because the bitmap has been moved in memory. Some people using GCHandle.Alloc()
to allocate memory in the CLR and pin it. Does Bitmap.LockBits()
do the same? I don't understand the difference between "locking" memory and "pinning" memory. Can you also explain the terminology and the differences if any?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Generic Generics in Managed C++
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
In your case an
attempted to access invalid memory
error is most probably caused by invalid memory allocation which you are doing in the unsafe part of code, e.g allocated array is smaller than number of pixels you are trying to put in that.There is also no need to think about pinning the objects unless your image data is less than 85000 Bytes as only objects less than 85K will be moved in memory.
Another story would be if you pass the object to unmanaged code, for example in the c++ library for faster processing. In this case your exception is very possible if the passed image gets out of scope and will be garbage collected. In this case you can use GCHandle.Alloc
(imageArray,GCHandleType.Pinned);
and than call Free if you do not need it any longer.GCHandle.Alloc
is a more generic method, that allows you to allocate a handle to any managed object and pin it in memory (or not). Pinning memory prevents GC from moving it around, which is especially useful when you have to pass some data, for example an array, to a unmanaged code.GCHandle.Alloc
will not help you access bitmap's data in any way, because pinning this object will just prevent the managed object from moving around (the Bitmap object) (and being garbage collected).Bitmap however is a wrapper around native GDI+'s
BITMAP
structure. It doesn't keep data in any managed array that you would have to pin, it just managed a native handle to GDI+ bitmap object. Because of thatBitmap.LockBits
is a way of telling this bitmap that you are interested in accessing it's memory, and it's just a wrapper aroundGdipBitmapLockBits
function. So your need of calling it has more to do with the fact that you are working with GDI+ bitmaps than with the fact, that you're working in managed environment with GC.Once you have used
LockBits
you should be able to access it's memory using pointers throughBitmapData.Scan0
- it's an address of first byte of data. You should not have problems as long, as you do not access memory behindBitmapData.Scan0 + Height * Stride
.And rememberto
UnlockBits
when you are done.