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

OpenCV: Stack Corruption with Unused Variable

提前提问

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


详情

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

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

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

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

这是他们的代码:

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 只是声明了,还没有(还)在任何地方使用。注释掉"fixes"这个问题。

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

这也发生在之前,在完全相同的情况下声明了 STL vector<> 而没有在相同的 class 中使用。不过我只是删除了它,因为我不需要它。

触发方式:

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

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() 只是 returns Original 来自 ImageVariants class。它不会以任何方式访问、设置或使用 SegmentedBounds

我知道的:

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

initModule_<module name>();

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

initModule_features2d();

我所有的问题都消失了,不需要陌生。我不确定为什么这些功能完全没有记录,因为我在任何地方都找不到它们的作用,但它们确实有效。

来源: 来自 this post 的 nikk 让我意识到了这些功能并节省了我的时间。