“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”的错误
初学C#,我想尝试用非安全代码来实现高斯滤波,但在执行下面代码时出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”的错误,不知错在哪儿呀?unsafe
{
byte* ptr1 = (byte*)(bmpData.Scan0);
for (int i = 0; i < curBitmap.Height; i++)
{
for (int j = 0; j < curBitmap.Width; j++)
{
double temp = 0;
for (int k = -radius; k <= radius; k++)
{
int rem = (Math.Abs(j + k)) % width;
byte* ptr2 = ptr1 + width * i + rem;
temp += (*ptr2) * filter[k + radius];
}
ptr1 = Convert.ToByte(temp); ptr1++;
}
ptr1 += bmpData.Stride - bmpData.Width * 3;
}
} --------------------编程问答-------------------- 有没有正确为你的指针分配内存以及初始化? --------------------编程问答-------------------- 指针已初始化
--------------------编程问答-------------------- 既然选了C#,就尽量不要用unsafe code。反正"safe code"是完全可以实现你要的功能,请参考:http://haishibai.blogspot.hk/2009/09/image-processing-c-tutorial-4-gaussian.html --------------------编程问答--------------------
你好好检查下,比如bmpData.Scan0,到底你为它分配了多少空间
byte* ptr2 = ptr1 + width * i + rem;这里对不对。 --------------------编程问答-------------------- 应该是越界了
ptr 代表的是指针,而不是byte
Ptr =convert...相当于你修改了指针,而不是指针指向的内容
--------------------编程问答-------------------- 指针我已分配内存,但还是不行呀 --------------------编程问答-------------------- unsafe
{
byte* ptr1 = (byte*)(bmpData.Scan0);
for (int i = 0; i < curBitmap.Height; i++)
{
for (int j = 0; j < curBitmap.Width; j++)
{
double temp = 0;
for (int k = -radius; k <= radius; k++)
{
int rem = (Math.Abs(j + k)) % width;
byte* ptr2 = ptr1 + width * i + rem;
temp += (*ptr2) * filter[k + radius];
}
*ptr1 = Convert.ToByte(temp);
ptr1++;
}
ptr1 += bmpData.Stride - bmpData.Width * 3;
}
} --------------------编程问答-------------------- 原来你是抄错了!
你有个致命的错误
for (int j = 0; j < curBitmap.Width; j++)不能用width,因为图像的宽度不是一个点一个byte
你需要 for (int j = 0; j < curBitmap.Stride; j++) --------------------编程问答-------------------- 改成for (int j = 0; j < curBitmap.Stride; j++) 还是出现一样的错误
--------------------编程问答-------------------- 自己仔细调试吧
所有用width的地方都要替换为stride
--------------------编程问答-------------------- 这就是 unsafe 的悲哀,你应该懂得。除非万不得已,否则不要写出这种代码。 --------------------编程问答-------------------- 加上上面大牛们的回贴再加一条
fixed ( byte* ptr1 = (byte*)(bmpData.Scan0))
{...}这样才不至于其他内存已损坏。
曾经有一本书上写过,你不fix住你的对象,你堆上的对象随时要因为垃圾清理时移动位置的,所以你必须fix住你要操作的对象,不让他随别的垃圾删除而移动了你的bmpData.Scan0位置 --------------------编程问答-------------------- 楼上,fixed关键字内是不支持强制转换的表达式的 --------------------编程问答-------------------- 代码改称如下,通过了调试,但标准差大于1.9以后,还是出现相同的错误呀,搞不懂呀
unsafe
{
System.IntPtr Scan0 = bmpData.Scan0;
byte* ptr = (byte*)(void*)Scan0;
for (int i = radius; i < bmpData.Height; i++)
{
for (int j = 0; j < bmpData.Width; j++)
{
byte* ptr1 = ptr + width * i + j;
double temp = 0;
for (int k = -radius; k <= radius; k++)
{
byte* ptr2 = ptr1 + k;
temp += (*ptr2)* filter[k + radius];
}
*ptr1 = Convert.ToByte(temp);
}
}
for (int j = 0; j < bmpData.Width; j++)
{
for (int i = radius; i < bmpData.Height; i++)
{
byte* ptr1 = ptr + width * i + j;
double temp = 0;
for (int k = -radius; k <= radius; k++)
{
byte* ptr2 = ptr1 + width * k;
temp += (*ptr2) * filter[k + radius];
}
*ptr1= Convert.ToByte(temp);
}
}
}
补充:.NET技术 , C#