OpenARK-SDK.exe 中 0x00007FF74F27A526 处的未处理异常:0xC00000FD:堆栈溢出(参数:0x0000000000000001、0x000000EEC5803FD

Posted

技术标签:

【中文标题】OpenARK-SDK.exe 中 0x00007FF74F27A526 处的未处理异常:0xC00000FD:堆栈溢出(参数:0x0000000000000001、0x000000EEC5803FD8)【英文标题】:Unhandled exception at 0x00007FF74F27A526 in OpenARK-SDK.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000EEC5803FD8) 【发布时间】:2017-06-01 03:41:35 【问题描述】:

以下代码 sn-p 导致 ***。

Unhandled exception at 0x00007FF74F27A526 in OpenARK-SDK.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000EEC5803FD8).

我该如何解决?它是我参与的open-source repository 的一部分,我希望不要在这里进行重大更改:

/***
Recursively performs floodfill on depthMap
***/
void DepthCamera::floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)

    if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] == 0.0)
        return;
    if (closeEnough(x, y, depthMap, 4, max_distance)) 
        mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
        depthMap.at<cv::Vec3f>(y, x)[0] = 0;
        depthMap.at<cv::Vec3f>(y, x)[1] = 0;
        depthMap.at<cv::Vec3f>(y, x)[2] = 0;
    
    else 
        return;
    

    floodFill(x + 1, y, depthMap, mask, max_distance);
    floodFill(x - 1, y, depthMap, mask, max_distance);
    floodFill(x, y + 1, depthMap, mask, max_distance);
    floodFill(x, y - 1, depthMap, mask, max_distance);


/***
Check whether candidate point is close enough to neighboring points
***/
bool DepthCamera::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)

    int num_close = 0;
    if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) 
        num_close++;
    
    if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) 
        num_close++;
    
    if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) 
        num_close++;
    
    if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) 
        num_close++;
    

    if (num_close >= num_neighbors) 
        return true;
    

    return false;

double Util::euclidianDistance3D(cv::Vec3f pt1, cv::Vec3f pt2)

    double dx = pt1[0] - pt2[0];
    double dy = pt1[1] - pt2[1];
    double dz = pt1[2] - pt2[2];

    return sqrtf(dx*dx + dy*dy + dz*dz);

调用者:

void DepthCamera::computeClusters(double max_distance, double min_size)

    clusters.clear();
    cv::Mat depthMap = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
    cv::medianBlur(xyzMap, depthMap, 3);
    cv::Mat mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
    for (int r = depthMap.rows - 1; r >= 0; r--) 
        for (int c = 0; c < depthMap.cols; c++) 
            if (depthMap.at<cv::Vec3f>(r, c)[2] > 0.2) 
                mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
                floodFill(c, r, depthMap, mask, max_distance);
                cv::Mat channels[3];
                cv::split(mask, channels);
                if (cv::countNonZero(channels[2]) > min_size) 
                    cv::medianBlur(mask, mask, 3);
                    clusters.push_back(mask.clone());
                
            
        
    

如果需要更多信息,请告诉我。基本上,当我靠近相机时,就会发生 *** 异常。

这是调用堆栈的屏幕截图:

这是我的一个screencast run without debugging

【问题讨论】:

你能看一下堆栈跟踪吗?堆栈溢出通常是过度递归或过度分配。一层一层往上看,看看那些看起来不对的变量。 @MonaJalal -- 很明显,您正在一遍又一遍地调用函数,一遍又一遍,一遍又一遍,等等,再次导致堆栈溢出。你的递归没有结束,你需要弄清楚为什么你的逻辑永远不会展开。 不,它告诉您递归的结束条件不完整或不正确。这可能由任何相机触发,具体取决于错误或设计缺陷。 您需要了解更多如何使用调试器,并且您(而不是我们)应该修复您的错误。堆栈溢出错误和无限递归很容易修复。 您正在使用使用大量堆栈的基本洪水填充算法。This Wikipedia article 处理此问题。 【参考方案1】:

递归的结束条件不完整或不正确。

如果您查看 Floodfill,会返回两种情况,一种触发递归。这告诉我们递归块不正确。具体来说,closeEnough() 没有按预期工作,因为您触发了一个永远不会返回 true 的案例。

您将查看传递给 closeEnough 的变量,以了解为什么它们永远不会满足它。只看代码,我就知道堆栈溢出的情况永远不会如此:

  if (num_close >= num_neighbors) 

我可以猜测哪些条件没有得到满足,但您可以通过查看传递给 closeEnough 的值更轻松地做到这一点。

如果这还不够,请给我们数值。

【讨论】:

当我按F10逐行调试它并在computeCluster的开头放置一个断点,并靠近相机甚至在我靠近相机时开始调试时,异常从来没有发生过,这使得当我run without debugging 时很难确定是什么值导致了异常 你的调试器是什么?在 Visual Studio 中,您可以只运行调试版本,等待它崩溃,然后在它崩溃后,您仍然可以查看堆栈的每个级别的变量。如果这不可能,您可以使用构建标志将每次调用 closeEnough(带有值)写入日志文件,这样您就可以在崩溃时以这种方式查看值。 在 Visual Studio + Windows 中,还可以为发布版本打开完整的故障转储。通过故障转储 + PDB 文件 + 源,您可以再次查看堆栈框架上调用的变量值。 如果您在没有调试的情况下运行:当崩溃发生时,如果您显示有关崩溃的详细信息,Windows 是否会为您提供“调试应用程序”的机会? (以“点击重试调试应用程序”为例) 如果没有,请登录到文件或阅读故障转储:msdn.microsoft.com/en-us/library/windows/desktop/…【参考方案2】:

虽然我认为这不是解决问题的最佳方法,但至少在我的情况下这是一个解决方法。

欢迎分享其他答案。

【讨论】:

真正的解决方法是迭代地而不是递归地编写代码。 @MichealWalz 在他的 cmets 中指出了这一点。如果您发现 2,000,000 字节的堆栈不够用怎么办?再增加一次? 我考虑使用本机 OpenCV 洪水填充算法并感谢您的反馈和链接。 docs.opencv.org/trunk/d5/d26/ffilldemo_8cpp-example.html

以上是关于OpenARK-SDK.exe 中 0x00007FF74F27A526 处的未处理异常:0xC00000FD:堆栈溢出(参数:0x0000000000000001、0x000000EEC5803FD的主要内容,如果未能解决你的问题,请参考以下文章

ppwjs之前端达人

新版测试中

初一下期中试卷

c++理解协程05

Access中VBA中excel文件中的VLookup

Groovy闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )