Question

I'm in .NET and using pointers to access raw image data. Currently I'm storing a reference to the Scan0 (and Stride) of the bitmap using:

BitmapData bmpData = bmp.LockBits(...);
*byte scan0 = (*byte)bmpData.Scan0;

Sometimes my program randomly crashes with errors like "Attempted to access protected memory". I'm assuming this is because my pointer becomes invalid after the .NET GC routinely compacts memory. So if I use IntPtr instead of the *byte pointer that I currently use, will the pointer remain valid after memory compaction?

BitmapData bmpData = bmp.LockBits(...);
IntPtr scan0 = bmpData.Scan0;

Obviously its near impossible to test this because I cannot replicate the "random" memory errors I'm getting, so I'm trying to arrive at a theoretically correct solution and hope it corrects my issues.

Edit: Please do not start a discussion on bitmap manipulation techniques. I just want to know if IntPtr is any better than *byte.

Was it helpful?

Solution

No, that's not a problem for bitmap pixel data. It is allocated in unmanaged memory, the garbage collector can't touch it. It is actually a memory-mapped file, the reason that loading or saving a bitmap puts a lock on the file. The LockBits() method ensures that memory-mapped file is mapped to memory and the view is stable. This kind of optimization is required because bitmaps can be very large and the memory for them should not be backed by the paging file.

Anyhoo, using byte* or IntPtr is not a problem, the memory they point to is guaranteed to be stable as long as the bitmap is locked.

The kind of problem you ought to be looking for is running off the end of the bitmap, you are using unsafe pointers so you won't get a friendly IndexOutOfRangeException. The AV however ought to be the next best diagnostic, assuming it actually occurs inside the code that's bracketed by the lock. Having a mismatch between the pointer type and the pixel format could be a cause. There's way too little code in the snippet to theorize beyond this.

OTHER TIPS

IntPtr is an integer that has the same size as a pointer. It does not get tracked by the GC.

The LockBits() method already ensures that the GC will not move the bitmap data around.

If you are getting access violations, there's two possible causes:

  • You are accessing memory outside of the bitmap (e.g. incorrect coordinates).
  • You are accessing the bitmap data after the UnlockBits() call
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top