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
。
我知道的:
- 我是一个非常有经验的C++开发者,所以像"you don't know what you are doing"这样的东西,只是一个未初始化的变量,循环越界,你复制粘贴代码了吗?等...不需要申请。这段代码写得很好,也很容易理解。
- 您看到的与变量关联的
Bounds
类型实际上只是一个奇特的结构。整个程序在很多方面都用得很彻底,没有任何问题。
Bounds
类型已经通过了所有严格的单元和集成测试,因此它没有任何根本性的错误。
经过大约两周的挣扎,我找到了答案。显然,某些 OpenCV 模块的某些功能要求您在使用之前调用一个函数来初始化模块:
initModule_<module name>();
我没有在我的问题中提到这个,但我在这个 class 中使用了 features2d
模块。具体来说,我使用的是该库中的 KeyPoints
对象。所以,在我添加的构造函数中:
initModule_features2d();
我所有的问题都消失了,不需要陌生。我不确定为什么这些功能完全没有记录,因为我在任何地方都找不到它们的作用,但它们确实有效。
来源: 来自 this post 的 nikk 让我意识到了这些功能并节省了我的时间。
提前提问
为什么 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
。
我知道的:
- 我是一个非常有经验的C++开发者,所以像"you don't know what you are doing"这样的东西,只是一个未初始化的变量,循环越界,你复制粘贴代码了吗?等...不需要申请。这段代码写得很好,也很容易理解。
- 您看到的与变量关联的
Bounds
类型实际上只是一个奇特的结构。整个程序在很多方面都用得很彻底,没有任何问题。 Bounds
类型已经通过了所有严格的单元和集成测试,因此它没有任何根本性的错误。
经过大约两周的挣扎,我找到了答案。显然,某些 OpenCV 模块的某些功能要求您在使用之前调用一个函数来初始化模块:
initModule_<module name>();
我没有在我的问题中提到这个,但我在这个 class 中使用了 features2d
模块。具体来说,我使用的是该库中的 KeyPoints
对象。所以,在我添加的构造函数中:
initModule_features2d();
我所有的问题都消失了,不需要陌生。我不确定为什么这些功能完全没有记录,因为我在任何地方都找不到它们的作用,但它们确实有效。
来源: 来自 this post 的 nikk 让我意识到了这些功能并节省了我的时间。