You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:42:42