C++实现魔棒工具递归导致退出码-11问题求助
解决魔棒工具递归过深导致进程退出的问题
问题描述
我正在编写一个魔棒工具,用于选中所有与起始像素相似的像素。在标记相似像素的脚本中,我使用了图像、容差T以及起始坐标x和y,采用递归实现功能。当使用小容差T时代码正常运行,但使用较大容差时会出现“进程退出码为-11”的错误,我认为问题是递归调用过深。程序从MWT函数启动,请问有谁知道如何解决该问题?提前感谢各位的建议。
用户提供的原代码:
#include "mwt.h" using namespace std; void checkSurroundings(const Image& image, vector<vector<bool>>& seen_pixels, const int& T, const unsigned int& x, const unsigned int& y, int x0, int y0) { seen_pixels.at(x0).at(y0) = true; if(x0 + 1 < 512 && seen_pixels.at(x0 + 1).at(y0) == false && abs(image.at(x).at(y) - image.at(x0 + 1).at(y0)) <= T) checkSurroundings(image, seen_pixels, T, x, y, x0 + 1, y0); if(x0 - 1 >= 0 && seen_pixels.at(x0 - 1).at(y0) == false && abs(image.at(x).at(y) - image.at(x0 - 1).at(y0)) <= T) checkSurroundings(image, seen_pixels, T, x, y, x0 - 1, y0); if(y0 + 1 < 512 && seen_pixels.at(x0).at(y0 + 1) == false && abs(image.at(x).at(y) - image.at(x0).at(y0 + 1)) <= T) checkSurroundings(image, seen_pixels, T, x, y, x0, y0 + 1); if(y0 - 1 >= 0 && seen_pixels.at(x0).at(y0 - 1) == false && abs(image.at(x).at(y) - image.at(x0).at(y0 - 1)) <= T) checkSurroundings(image, seen_pixels, T, x, y, x0, y0 - 1); return; } vector<vector<bool>> MWT(const Image& image, const unsigned int x, const unsigned int y, const unsigned int T) { const unsigned int height = image.at(0).size(); const unsigned int width = image.size(); vector<vector<bool>> seen_pixels(width, vector<bool>(height, false)); checkSurroundings(image, seen_pixels, T, x, y, x, y); return seen_pixels; }
问题原因
进程退出码-11是段错误,确实由递归调用过深导致:当容差T较大时,需要遍历的像素数量剧增,递归调用栈的深度会超过操作系统给进程分配的栈空间上限,最终触发栈溢出,导致程序崩溃。
解决方案
将递归实现改为迭代实现,用标准库的stack容器模拟递归调用栈,所有待处理的像素坐标存储在堆内存中,不受调用栈大小限制。同时修复原代码中硬编码图像尺寸的问题,适配不同大小的图像:
#include "mwt.h" #include <stack> // 引入stack头文件 using namespace std; // 定义结构体存储像素坐标 struct Pixel { int x; int y; Pixel(int x_, int y_) : x(x_), y(y_) {} }; vector<vector<bool>> MWT(const Image& image, const unsigned int x, const unsigned int y, const unsigned int T) { const unsigned int width = image.size(); const unsigned int height = image.at(0).size(); vector<vector<bool>> seen_pixels(width, vector<bool>(height, false)); stack<Pixel> pixel_stack; // 起始像素入栈并标记已访问 pixel_stack.emplace(x, y); seen_pixels[x][y] = true; // 迭代处理所有待检查的像素 while (!pixel_stack.empty()) { Pixel curr = pixel_stack.top(); pixel_stack.pop(); int x0 = curr.x; int y0 = curr.y; // 检查右侧相邻像素 if (x0 + 1 < width && !seen_pixels[x0 + 1][y0] && abs(image.at(x).at(y) - image.at(x0 + 1).at(y0)) <= T) { seen_pixels[x0 + 1][y0] = true; pixel_stack.emplace(x0 + 1, y0); } // 检查左侧相邻像素 if (x0 - 1 >= 0 && !seen_pixels[x0 - 1][y0] && abs(image.at(x).at(y) - image.at(x0 - 1).at(y0)) <= T) { seen_pixels[x0 - 1][y0] = true; pixel_stack.emplace(x0 - 1, y0); } // 检查下方相邻像素 if (y0 + 1 < height && !seen_pixels[x0][y0 + 1] && abs(image.at(x).at(y) - image.at(x0).at(y0 + 1)) <= T) { seen_pixels[x0][y0 + 1] = true; pixel_stack.emplace(x0, y0 + 1); } // 检查上方相邻像素 if (y0 - 1 >= 0 && !seen_pixels[x0][y0 - 1] && abs(image.at(x).at(y) - image.at(x0).at(y0 - 1)) <= T) { seen_pixels[x0][y0 - 1] = true; pixel_stack.emplace(x0, y0 - 1); } } return seen_pixels; }
关键修改点
- 移除递归函数
checkSurroundings,改用stack容器存储待处理的像素坐标 - 每次从栈顶取出像素,检查其四个邻接像素,符合条件的标记为已访问并压入栈
- 替换原代码中硬编码的
512为width和height变量,避免图像尺寸不匹配导致的越界错误 - 所有数据存储在堆内存中,彻底解决递归栈溢出的问题
内容的提问来源于stack exchange,提问作者mari091109
相关产品推荐
相关产品推荐

