我的 CS50 模糊滤镜上的 UndefinedBehaviorSanitizer
UndefinedBehaviorSanitizer on my CS50 Blur Filter
我似乎无法弄清楚为什么这个错误不断发生。我对编码还很陌生,这个程序应该使用框模糊来模糊图像,但是当我尝试执行该程序时出现错误。我知道这可能不是最有效的解决方案,但我将不胜感激有关如何让它工作的任何提示!
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE old[height][width];
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
old[i][j] = image[i][j];
}
}
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
//top left corner
if(j == 0 && i == 0)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue) /4);
}
//top right corner
else if(j == width && i == 0)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j-1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j-1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j-1].rgbtBlue) /4);
}
//bottom left corner
else if(j == 0 && i == height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue) /4);
}
//bottom right corner
else if(j == width && i == height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue) /4);
}
//first row
else if(i == 0 && j > 0 && j < width - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j-1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j-1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j-1].rgbtBlue) /6);
}
//last row
else if(i == height && j > 0 && j < width - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i-1][j-1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i-1][j-1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i-1][j-1].rgbtBlue) /6);
}
//first column
else if(j == 0 && i > 0 && i < height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue) /6);
}
//last column
else if(j == width && i > 0 && i < height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue) /6);
}
else if(i < height - 1 && j < width - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed + old[j-1][i+1].rgbtRed) /9);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen + old[j-1][i+1].rgbtGreen) /9);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue + old[j-1][i+1].rgbtBlue) /9);
}
}
}
}
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==9889==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7fff298bd0b8 (pc 0x000000442a96 bp 0x7fff298bc2b0 sp 0x7fff298071c0 T9889)
==9889==The signal is caused by a READ memory access.
#0 0x442a95 (/home/ubuntu/pset4/filter/filter+0x442a95)
#1 0x4232f1 (/home/ubuntu/pset4/filter/filter+0x4232f1)
#2 0x7f302ce5db96 (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x402e19 (/home/ubuntu/pset4/filter/filter+0x402e19)
UndefinedBehaviorSanitizer can not provide additional info.
==9889==ABORTING
当您尝试对如此多的边缘情况进行硬编码时(字面意思是呵呵),出现问题是可以预料的。为什么不尝试矩阵遍历呢?即构造一个假想矩阵,以当前像素([i][j]
)为中心,遍历该矩阵的所有有效像素并相加。简单高效。
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE old[height][width];
for (int i = 0; i < height; i++)
{
// Copy the original image over to a temporary variable, row by row
memcpy(old[i], image[i], sizeof(RGBTRIPLE) * width);
}
// Iterate through rows
for (int i = 0; i < height; i++)
{
// Iterate through columns
for (int j = 0, red, green, blue, count; j < width; j++)
{
// Reset the variables
red = blue = green = count = 0;
// Move row-wise in the imaginary matrix (centered around [i][j])
for (int r = i - 1; r <= i + 1; r++)
{
// Move column-wise in the imaginary matrix (centered around [i][j])
for (int c = j - 1; c <= j + 1; c++)
{
// Check for invalid pixels
if (r < 0 || r > height - 1)
{
// Invalid row, no need to continue, move on to next row
break;
}
if (c > -1 && c < width)
{
// Valid pixel
count++;
// Sum up every pixel color
red += old[r][c].rgbtRed;
green += old[r][c].rgbtGreen;
blue += old[r][c].rgbtBlue;
}
}
}
// Calculate the average and assign
image[i][j].rgbtRed = round((float)red / count);
image[i][j].rgbtGreen = round((float)green / count);
image[i][j].rgbtBlue = round((float)blue / count);
}
}
return;
}
这与您想要实现的相同,除了围绕每个像素构造一个虚构矩阵,并检查内部索引 所述矩阵 - 我们使这个问题简单得多。
“我似乎无法弄清楚为什么这个错误不断发生。”
(关于异常信号:==9889==The signal is caused by a READ memory access.
)
虽然我同意其他答案中提供的建议,但它没有解决您提出的核心问题,这很可能是由您代码中某处未定义的行为引起的。
注意:错误陈述:signal is caused by a READ memory access.
是 undefined behavior, (UB) for which my favorite definition 的症状与您所看到的相符。具体来说,您的代码在某些时候试图写入不属于它的内存。如果正在写入的无主内存恰好不属于任何其他进程,那么您的程序甚至可能不会抛出异常。但是在你的情况下,很可能你的进程不拥有的内存 是 由另一个进程拥有,导致 OS 抱怨并发出你正在侵入的异常信号另一个的属性(内存位置)。
有趣的是,您 post 编辑的代码没有明显迹象表明赋值试图访问不属于自己的内存。为所有赋值绑定嵌套循环的条件:
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
显然不允许 i
或 j
索引超出 image
数组的边界。
以及随后的语句如:
else if(j == width && i == 0)
被 for 循环中的条件限制 运行 永远不允许 j == width
,从而防止 可能 尝试编写 for image[i][j].rgbtRed
的例子(如果 j == width
会使数组的一个内存位置超出范围。)并且是异常的原因。
所以我建议可能是代码未posted导致异常发生。 (您从未回答 评论中的问题 错误发生的确切位置。)您还没有找到它。找到根本原因并将其消除是一个很好的举措。
或者,您可以 post 一个 minimal but complete, compilable example 从而更好地让访问此 post 的其他人帮助您找到它。
EDIT - 我 运行 你的代码只有一个 main()
函数(见下文)执行此操作,但在您post编辑 的代码片段中没有发现读取内存访问违规的证据。我坚信此时问题出在其他地方,也许在您没有包括的一段代码中:
typedef struct {
int rgbtRed;
int rgbtGreen;
int rgbtBlue;
}RGBTRIPLE;
void blur(int height, int width, RGBTRIPLE image[height][width]);
int main(void)
{
RGBTRIPLE image[2][3] = {{{12,13,14},{14,15,16},{15,16,17}},{{16,17,18},{17,18,19},{18,19,20}}};
blur(2, 3, image);
return 0;
}
在场景中,例如j==width-1
,对 old[i][j+1]
的访问将超出内部数组的末尾。尽管丹尼斯·里奇 (Dennis Ritchie) 设计的 C 语言允许超出内部数组边界但最终位于外部数组内的访问,但如果尝试进行此类访问,该标准允许实现陷入陷阱或行为异常。我怀疑 UndefinedbehaviorSanitizer 正在标记此类访问。
我似乎无法弄清楚为什么这个错误不断发生。我对编码还很陌生,这个程序应该使用框模糊来模糊图像,但是当我尝试执行该程序时出现错误。我知道这可能不是最有效的解决方案,但我将不胜感激有关如何让它工作的任何提示!
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE old[height][width];
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
old[i][j] = image[i][j];
}
}
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
//top left corner
if(j == 0 && i == 0)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue) /4);
}
//top right corner
else if(j == width && i == 0)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j-1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j-1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j-1].rgbtBlue) /4);
}
//bottom left corner
else if(j == 0 && i == height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue) /4);
}
//bottom right corner
else if(j == width && i == height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed) /4);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen) /4);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue) /4);
}
//first row
else if(i == 0 && j > 0 && j < width - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j-1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j-1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j-1].rgbtBlue) /6);
}
//last row
else if(i == height && j > 0 && j < width - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i-1][j-1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i-1][j-1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i-1][j-1].rgbtBlue) /6);
}
//first column
else if(j == 0 && i > 0 && i < height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue) /6);
}
//last column
else if(j == width && i > 0 && i < height - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed) /6);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen) /6);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue) /6);
}
else if(i < height - 1 && j < width - 1)
{
image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed + old[j-1][i+1].rgbtRed) /9);
image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen + old[j-1][i+1].rgbtGreen) /9);
image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue + old[j-1][i+1].rgbtBlue) /9);
}
}
}
}
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==9889==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7fff298bd0b8 (pc 0x000000442a96 bp 0x7fff298bc2b0 sp 0x7fff298071c0 T9889)
==9889==The signal is caused by a READ memory access.
#0 0x442a95 (/home/ubuntu/pset4/filter/filter+0x442a95)
#1 0x4232f1 (/home/ubuntu/pset4/filter/filter+0x4232f1)
#2 0x7f302ce5db96 (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x402e19 (/home/ubuntu/pset4/filter/filter+0x402e19)
UndefinedBehaviorSanitizer can not provide additional info.
==9889==ABORTING
当您尝试对如此多的边缘情况进行硬编码时(字面意思是呵呵),出现问题是可以预料的。为什么不尝试矩阵遍历呢?即构造一个假想矩阵,以当前像素([i][j]
)为中心,遍历该矩阵的所有有效像素并相加。简单高效。
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE old[height][width];
for (int i = 0; i < height; i++)
{
// Copy the original image over to a temporary variable, row by row
memcpy(old[i], image[i], sizeof(RGBTRIPLE) * width);
}
// Iterate through rows
for (int i = 0; i < height; i++)
{
// Iterate through columns
for (int j = 0, red, green, blue, count; j < width; j++)
{
// Reset the variables
red = blue = green = count = 0;
// Move row-wise in the imaginary matrix (centered around [i][j])
for (int r = i - 1; r <= i + 1; r++)
{
// Move column-wise in the imaginary matrix (centered around [i][j])
for (int c = j - 1; c <= j + 1; c++)
{
// Check for invalid pixels
if (r < 0 || r > height - 1)
{
// Invalid row, no need to continue, move on to next row
break;
}
if (c > -1 && c < width)
{
// Valid pixel
count++;
// Sum up every pixel color
red += old[r][c].rgbtRed;
green += old[r][c].rgbtGreen;
blue += old[r][c].rgbtBlue;
}
}
}
// Calculate the average and assign
image[i][j].rgbtRed = round((float)red / count);
image[i][j].rgbtGreen = round((float)green / count);
image[i][j].rgbtBlue = round((float)blue / count);
}
}
return;
}
这与您想要实现的相同,除了围绕每个像素构造一个虚构矩阵,并检查内部索引 所述矩阵 - 我们使这个问题简单得多。
“我似乎无法弄清楚为什么这个错误不断发生。”
(关于异常信号:==9889==The signal is caused by a READ memory access.
)
虽然我同意其他答案中提供的建议,但它没有解决您提出的核心问题,这很可能是由您代码中某处未定义的行为引起的。
注意:错误陈述:signal is caused by a READ memory access.
是 undefined behavior, (UB) for which my favorite definition 的症状与您所看到的相符。具体来说,您的代码在某些时候试图写入不属于它的内存。如果正在写入的无主内存恰好不属于任何其他进程,那么您的程序甚至可能不会抛出异常。但是在你的情况下,很可能你的进程不拥有的内存 是 由另一个进程拥有,导致 OS 抱怨并发出你正在侵入的异常信号另一个的属性(内存位置)。
有趣的是,您 post 编辑的代码没有明显迹象表明赋值试图访问不属于自己的内存。为所有赋值绑定嵌套循环的条件:
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
显然不允许 i
或 j
索引超出 image
数组的边界。
以及随后的语句如:
else if(j == width && i == 0)
被 for 循环中的条件限制 运行 永远不允许 j == width
,从而防止 可能 尝试编写 for image[i][j].rgbtRed
的例子(如果 j == width
会使数组的一个内存位置超出范围。)并且是异常的原因。
所以我建议可能是代码未posted导致异常发生。 (您从未回答 评论中的问题 错误发生的确切位置。)您还没有找到它。找到根本原因并将其消除是一个很好的举措。
或者,您可以 post 一个 minimal but complete, compilable example 从而更好地让访问此 post 的其他人帮助您找到它。
EDIT - 我 运行 你的代码只有一个 main()
函数(见下文)执行此操作,但在您post编辑 的代码片段中没有发现读取内存访问违规的证据。我坚信此时问题出在其他地方,也许在您没有包括的一段代码中:
typedef struct {
int rgbtRed;
int rgbtGreen;
int rgbtBlue;
}RGBTRIPLE;
void blur(int height, int width, RGBTRIPLE image[height][width]);
int main(void)
{
RGBTRIPLE image[2][3] = {{{12,13,14},{14,15,16},{15,16,17}},{{16,17,18},{17,18,19},{18,19,20}}};
blur(2, 3, image);
return 0;
}
在场景中,例如j==width-1
,对 old[i][j+1]
的访问将超出内部数组的末尾。尽管丹尼斯·里奇 (Dennis Ritchie) 设计的 C 语言允许超出内部数组边界但最终位于外部数组内的访问,但如果尝试进行此类访问,该标准允许实现陷入陷阱或行为异常。我怀疑 UndefinedbehaviorSanitizer 正在标记此类访问。