Aut*_*ass 1 c++ opencv visual-studio-2010
我有一个使用 openCV 2.4.10 在 Visual Studio 2010 中编写的简单代码,它从某些输入文件中提取一些功能。
Mat extractSIFT(Mat img)
{
cv::Ptr<cv::FeatureDetector> detector;
cv::Ptr<cv::Feature2D> descriptorExtractor;
detector = cv::FeatureDetector::create("Dense");
descriptorExtractor = cv::DescriptorExtractor::create("SIFT");
detector->set("initXyStep",GRID_SPACING);
vector<cv::KeyPoint> keypoints;
detector->detect(img,keypoints);
Mat o;
//Mat o(keypoints.size(),128,CV_8U);
descriptorExtractor->compute(img,keypoints,o);
return o;
}
Run Code Online (Sandbox Code Playgroud)
尽管此代码在调试模式下工作正常(尽管很慢),但它给出了以下错误:
Windows 在 Prototype.exe 中触发了断点。
这可能是由于堆损坏造成的,这表明 Prototype.exe 或其加载的任何 DLL 中存在错误。
这也可能是由于用户在 Prototype.exe 获得焦点时按了 F12。
输出窗口可能有更多诊断信息。
经过进一步调查,我发现输出变量 o 在发布模式(悬停在上方)下看不到,但可以在简单的控制台转储上打印值。
在反汇编程序中:
848: //Mat o(keypoints.size(),128,CV_8U);
849: descriptorExtractor->compute(img,keypoints,o);
850:
851: return o;
013F6FCF 56 push esi
013F6FD0 8D 55 C0 lea edx,[keypoints]
013F6FD3 52 push edx
013F6FD4 8D 45 0C lea eax,[img]
013F6FD7 50 push eax
013F6FD8 8B CF mov ecx,edi
013F6FDA C7 45 F0 01 00 00 00 mov dword ptr [ebp-10h],1
013F6FE1 E8 42 35 02 00 call cv::Feature2D::compute (141A528h)
013F6FE6 8B 45 C0 mov eax,dword ptr [keypoints]
013F6FE9 3B C3 cmp eax,ebx
013F6FEB 74 09 je extractSIFT4+306h (13F6FF6h)
013F6FED 50 push eax
**013F6FEE E8 EC 5C 02 00 call operator delete (141CCDFh)**
013F6FF3 83 C4 04 add esp,4
Run Code Online (Sandbox Code Playgroud)
错误发生与星号一致。我尝试了几个项目属性(/Md,MT,增量构建,...)重新编译openCV,检查平台版本(v100)但无济于事。
对于任何类型的堆损坏,Microsoft Application Verifier(免费软件)都是无价的。您需要使用 Basics\Heaps 检查来配置它,我建议第一次禁用所有其他检查。保存设置后,您将需要重新启动程序。它会在腐败点崩溃。
例如:假设您在堆上分配了 100 个字节,然后尝试写入 101 个字节。在调试版本中,C++ CRT 将在块之前和之后添加一些额外的填充,这将防止和检测小堆损坏。在发布版本中,没有填充并且堆被损坏,您通常在进行其他堆操作时才意识到这一点为时已晚。使用应用程序验证器,您的程序将在写入第 101 个字节时准确地崩溃到调试器中。当发生这种情况时,您可以在 Visual Studio 的输出窗口中看到一些额外的详细信息。
(注意:我总是为我开发的程序启用带有 Basics\Heaps 的应用程序验证器)
在这种特定情况下,您可能会看到向量的析构函数导致崩溃。这意味着没有发生堆损坏,但程序正在尝试删除不存在的堆块。这很可能是由于链接了使用不同编译器或不同调试/发布设置编译的 OpenCV。类的结构vector和分配的块填充在编译器和调试/发布之间有所不同。
更新: 既然我们知道了不同 CRT 的情况,这里有一个扩展的解释。