为什么位图扫描0在解锁后仍然有效?



据我所知,在垃圾收集器负责内存管理的托管环境中没有指针的概念。就像有人想操作位图中的像素值一样,她/他必须首先像下面的代码一样锁定它。

Bitmap Image = new Bitmap(width, height, 
System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = Image.LockBits(rect, ImageLockMode.ReadWrite, 
PixelFormat.Format8bppIndexed);
IntPtr imageScan0 = bmpData.Scan0;
unsafe
{
byte* ptr = (byte*)imageScan0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
*ptr++ = 128;
}
}
}
Image.UnlockBits(bmpData);

我的主要问题是: 如果我存储 imageScan0 信息,然后解锁位图,我仍然可以使用 imageScan0 来操作其值,就像在锁定和解锁操作之间操作它一样。

我已经测试过它,我很惊讶地看到imageScan0仍然有效。 我的猜测是基础位图驻留在非托管内存上。

我的主要问题是:如果我存储 imageScan0 信息,然后解锁位图,我仍然可以使用 imageScan0 来操作其值,就像我在锁定和解锁操作之间操作它一样。

您可以。但这并不意味着你可以

该系统只是没有设计为在您解锁内存时立即使内存 100% 失效。锁给了你一个指针,并承诺在你解锁之前的持续时间内,该指针将保持有效。

但反之则不然。系统不保证指针在您解锁后会立即失效。

但这并不意味着你可以使用它。您已经告诉系统您已完成指针。现在,它可以随时自由移动、使其无效,无论它想要什么。如果你继续使用它,你就是在玩火。

指针在解锁后保持有效本身不是问题。使用它对您来说是一个问题;确保你不这样做是你的工作,而不是系统的。

最新更新