OpenCV:使用未使用变量的堆栈损坏

时间:2015-03-28 05:22:02

标签: c++ debugging opencv stack-corruption

问题前面

为什么简单包含SegmentedBounds导致堆栈损坏?它从未被使用过(还),我可以在腐败警告之后继续执行该程序而没有任何明显的不利影响。


详细

我在Visual Studio 2013中有一个OpenCV 2.4.10项目,它突然开始导致堆栈损坏错误:

Run-Time Check Failure #2 - Stack around the variable 'was_processed' was corrupted!

有趣的是,这是OpenCV框架的一部分,而不是我的代码。它在sources/modules/highgui/src/window_w32.cpp函数中的WindowProc()内失败。

我可以继续完成该计划,但没有明显的不利影响。

以下是他们的代码:

static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    LRESULT ret;

    if( hg_on_preprocess )
    {
        int was_processed = 0;
        int rethg = hg_on_preprocess(hwnd, uMsg, wParam, lParam, &was_processed);
        if( was_processed )
            return rethg;
    }
    ret = HighGUIProc(hwnd, uMsg, wParam, lParam);

    if(hg_on_postprocess)
    {
        int was_processed = 0;
        int rethg = hg_on_postprocess(hwnd, uMsg, wParam, lParam, &was_processed);
        if( was_processed )
            return rethg;
    }

    return ret;
} // <================= Debugger says it stopped here

这是我的代码:

class ImageVariants {
public:
    Mat getOriginal() const;
    ...

private:
    Point3i Bounds3D;
    SubjectFace Face;
    Mat Mask;
    Mat Original;
    Bounds SegmentedBounds; // PROBLEMS
    Bounds Subject;

    bool boundsSet = false;
};

失败的原因:

这是踢球者,SegmentedBounds仅在任何地方声明而不是(尚未)使用。评论它“修复”了这个问题。

此外,如果变量属于Bounds*类型,则不存在损坏。看起来如果ImageVariants的内存占用超过一定的大小,那么我们就会遇到问题。

这也发生在之前,在声明STL vector<>并且未在同一类中使用的完全相同的情况下。我刚刚删除它,因为我不需要它。

如何触发:

我使用OpenCV的HighGUI工具与程序进行交互。每当我从ImageVariants类访问一个函数时,它似乎都是bork:

Scalar color(255.0, 0.0, 0.0);
Point end(x, y);

//Draw the rectangle the user is drawing
Mat img = w->Segmenter.Variants.getOriginal();

rectangle(img, w->MouseStart, end, color, 1, 8, 0);
w->draw(&img);

getOriginal()只返回Original课程中的ImageVariants。它不以任何方式访问,设置或使用SegmentedBounds

我所知道的:

  • 我是一位非常有经验的C ++开发人员,所以“你不知道自己在做什么”,只是一个未初始化的变量,循环出界,你复制并粘贴了代码吗?等...不需要申请。这段代码写得很好并且理解得很好。
  • 您看到与变量关联的Bounds类型实际上只是一个奇特的结构。它在整个程序中以非常彻底的方式使用,没有任何问题。
  • Bounds类型已经通过了所有严格的单元和集成测试,因此没有任何根本性的错误。

1 个答案:

答案 0 :(得分:0)

经过大约两周的挣扎,我找到了答案。显然,某些OpenCV模块的某些功能要求您在使用之前调用函数来初始化模块:

initModule_<module name>();

我在我的问题中没有提到这一点,但是我在这个课程中使用了features2d模块。具体来说,我使用的是该库中的KeyPoints对象。所以,在构造函数中我添加了:

initModule_features2d();

我的所有问题都消失了,不需要陌生。我不确定为什么这些功能完全没有记录,因为我无法在任何地方找到他们甚至做的事情,但他们的工作。

信用:来自this post的nikk让我意识到这些功能,并节省了我的培根,很长时间。