C++ 编译引入错误
C++ Compilation introduce errors
我在Visual Studio 2010中有一个多线程C++Windows项目,它使用Qt(5.1.1)和OpenCV(2.4.8)。当我在调试模式下构建它时,一切运行正常,但是当我在发布模式下构建它时,程序崩溃了。两种配置几乎相同(仅在版本中我有多线程 DLL/MD 和调试多线程调试 DLL/MDd),我禁用了版本的优化,甚至启用了调试以捕获错误。最奇怪的是,崩溃的同一段代码在另一个控制台项目中运行良好。
该错误是OpenCV代码内部的,它与我的代码无关,我的代码只是:
void MyProject::findEllipses(QImage &frame, vector<RotatedRect> &ellipses)
{
Mat image = Mat(frame.height(), frame.width(), CV_8UC4, frame.scanLine(0));
cvtColor(image, image, CV_RGB2GRAY);
GaussianBlur(image, image, Size(3, 3), 0, 0, 4);
threshold(image, image, treshVal, 255, THRESH_BINARY);
vector<vector<Point> > contours;
Mat contoursImage = image.clone();
findContours(contoursImage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE, Point(0, 0));
// ....Mode Code
正如我在调试中所说,代码运行没有问题,findContours
调用_contours.create(total, 1, 0, -1, true);
(在 OpenCV 轮廓的第 1720 行.cpp)并继续使用该方法。但是在Release中,当我单步进入_contours.create(total, 1, 0, -1, true)
时,程序没有执行该方法,而是跳转到void _OutputArray::clear() const
(matrix.cpp 的第 1674 行)并被困在那里,因为它在第一行调用int k = kind();
,而不是调用cv::kind()
,而是调用:
int _InputArray::type(int i) const
{
int k = kind();
它再次调用 againgkind()
再次调用type()
(而不是应有的kind()
),进行无限递归循环,带来堆栈溢出。
我尝试创建一个新的Visual Studio 2010项目,以查看这是否是项目创建问题,但问题仍然存在。
我的猜测是函数地址在发布模式下是错误的,所以当它尝试调用create()
时,它会调用另一个地址,在堆栈中弄得一团糟,但这只是我的猜测。起初我会责怪 OpenCV 发布的 dll,但是,正如我所说,在另一个仅运行该特定代码的控制台项目中,代码在机器人构建模式下运行良好。我不明白我的其他线程和代码如何触发此行为,因为错误归结为 OpenCV 中的错误函数调用。
这超出了我的知识范围,我不知道如何解决这个问题,我很感激在这个问题上能得到的所有帮助,因为我已经提出了我所有的想法来解决这个问题......
编辑:
我做了一个小项目,这样任何人都可以看到正在发生的事情。
这些文件位于: https://app.box.com/s/3owljl44emv57erinrf8
为了运行它,您必须具有OpenCV 2.4.8和Qt 5.1.1,并配置Visual Studio 2010项目以从正确的位置获取包含文件。在资源文件夹中有一个将加载的图像,在 SaraVisualControl.cpp第 20 行中,您必须放置正确的图像路径,抱歉我没有自动执行此操作,但我急于将其打包到一个小项目中。关于如何运行它的任何其他问题,请告诉我。
编辑 2
我发现了这个旧线程:http://code.opencv.org/issues/2218 用户似乎遇到了与我相同的问题,并且只是在关闭OPENCV_CAN_BREAK_BINARY_COMPATIBILITY的情况下运行 CMake 似乎可以解决它。但是这个选项在新版本的OpenCV中不再存在,如 http://code.opencv.org/issues/2358 中所述。有谁知道这其中的含义以及它之间的关系?
我过去在混合 VC 运行时版本时遇到过类似的症状。如果您使用的是VC2010,而OpenCV 2.4.8是在2012年甚至2013年构建的,那么您的ABI不匹配。 例如,内存 std::vector 的布局不同,可能是 vtable 中某些方法的顺序发生了变化,等等。
测试这一点的一种简单方法是在调试时检查"模块"窗口并查找更高版本的运行时 dll。您的是msvcr100d.dll,如果您看到msvcr110d或120d - 这可能是来源。 (假设您和 OpenCV 都动态链接到 CRT - 我无法判断)。
调试和发布在内存分配方面是不同的。通常在调试模式下,分配更大。 可能是你滥用了一些openCV电话,但你没有意识到这一点。 我会做下一步行动:
-
验证帧是否正常。可能是太大,或者宽度或高度没有启动;
-
验证下一行之后图像变量是否正常
垫子图像 = Mat(frame.height(), frame.width(), CV_8UC4, rame.scanLine(0));
当 第一个和第二个参数相同时,是否可以调用 cvtColor(可能是你在这里滥用了 CV)
当第一个和第二个参数相同时调用高斯模糊可以吗?尝试放置不同的第二个参数
阈值函数调用也是如此
检查在 image.clone 调用后,countoursImage 是否为有效矩阵。
我猜:除了检查库本身是否正确之外,还要检查是否以相同的顺序(在所有构建中)指定所有库。否则,链接器可能会在最终链接器阶段将函数名称绑定到不同的实现。
我遇到了同样的问题。我正在使用Qt 5.1.1和opencv248,我的应用程序在从findcontours返回后崩溃。事实证明,我在pro文件中使用了vc10库和相应的dll,而正在使用的Qt编译器是msvc2013。切换到opencv 12中的vc248文件夹为我解决了这个问题。
您是否检查过 opencv 库的发布版本。 Opencv 为发布版和调试版提供了不同的库集。如果您已允许在发布模式下包含调试库。您的代码将编译时没有错误,但在执行时会抛出 excecption。 检查您的库 转到
Project->Properties->Configuration Properties->linker->Input->Additional Dependencies.
确保发布模式中没有一个 Opencv 库以"d"结尾。
发布库:"opencv_core248.lib">
用于调试的库:"opencv_core248d.lib">
请注意调试模式末尾的D。
我希望这会有所帮助。
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- std::is_base_of表示ctor编译错误
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- Qt Cmake 错误编译"GuiSupportQt not found"
- Opengl 精度转换错误编译错误 E0415
- 库将ARM架构错误编译为架构X64
- RT 音频 Mac 错误 g++ 编译错误
- 错误编译Boost.log
- 错误编译QT创建者 / QT窗口小部件示例
- 错误编译MIPS32
- Visual Studio 2013 中的错误(编译和运行代码)
- 链接错误编译qt项目在visual 2010
- 无法用模板错误编译nsgmls
- 奇怪的错误.编译失败
- 如果有人调用c++中的方法,则强制错误(编译时)
- 来自autoconf测试的错误编译命令
- 时间限制超出错误C++编译
- SFML 2.3 和 CodeBlocks 错误编译