嗨我写了一个简单的程序
Main.cpp
std::vector<cv::Mat> PD_Classifier_VEC;
#define Folder_Address ""
int Main()
{
int overall_counter=0;
for(int j = 0 ; j < 600 ; j++)
{
QString address = Folder_Address + QString::number(overall_counter++) +".jpg";
cv::Mat image = cv::imread(address.toUtf8().constData(),0);
PD_Classifier_VEC.push_back(image);
PD();
}
}
PD功能
void PD()
{
static int Total_Frame_Number=0;
Total_Frame_Number++;
cv::Mat Point_MAT = cv::Mat(PD_Classifier_VEC[0].size(),CV_8UC1,cv::Scalar::all(0));
....//Some Calculation //
PD_Classifier_VEC[0].release();
PD_Classifier_VEC.erase(PD_Classifier_VEC.begin());
}
这段代码工作正常直到j=56,之后Qt显示这个错误并退出!!!
*** Error in `/home/parsa/QtProjects/QtVLPR/QtVLPR': corrupted double-linked list: 0x0000000000dcf880 ***
我在调试器模式下运行代码,并将以下if语句代码添加到PD()函数:
void PD()
{
static int Total_Frame_Number=0;
Total_Frame_Number++;
cv::Mat Point_MAT = cv::Mat(PD_Classifier_VEC[0].size(),CV_8UC1,cv::Scalar::all(0));
....//Some Calculation //
if(Total_Frame_Number==56)
{
std::cout<<Point_MAT<<"\n"; //it displays the elements perfectly
int Nonz = cv::countNonZero(Point_MAT); //it runs too
cv::imshow("Point_MAT",Point_MAT); //here the error appears !!!
cv::waitKey();
}
PD_Classifier_VEC[0].release();
PD_Classifier_VEC.erase(PD_Classifier_VEC.begin());
}
正如你所看到的,前两行上面提供的注解工作正常,但是当我试图用imshow显示图像时,程序崩溃了,显示了corrupted double linked list错误!
为什么我不能显示这个图像,如果POINT_MAT图像损坏,前两行如何正常工作?
P.S如果我从j=57开始程序,它工作正常,直到它完成,没有错误出现,所以
//some calculation
代码工作正常,我对此很肯定。
我已经测试了许多其他功能,如阈值,减去和...这对图像的数据部分的工作,他们的工作很好,但当我添加一个功能,对元数据+数据部分的损坏的双链接列表再次出现!!!
cv::subtract(Point_MAT,Point_MAT,temp); //works fine because it only works on data part
Point_MAT.copyTo(Temp_MAT); //gives error cause it works on header part too ...
2条答案
按热度按时间5jvtdoz21#
这个错误来自标准的C库,表明您已经损坏了堆。
具体来说,除非在 * 您自己的代码 * 中有匹配的
addref()
,否则不应该在Cv::mat
上调用release()
。Cv::mat
的行为类似于Qt中常见的隐式共享值(例如QImage
),您不应该担心手动管理它的引用计数。显而易见的建议是删除“一些计算”部分。对于更多的图像,你显示的代码 as is 应该可以在没有计算的情况下工作(没有
release()
)。将您显示的代码转换为单独的单个文件项目,并确保它可以运行-因为它应该运行。然后,错误仅限于您的计算-只有当您进行计算时,错误才会显现出来,这是计算问题的症状。
也许是计算分配了内存?
下面是一个运行良好的自包含示例,它演示了所示代码不仅正常,而且即使您一次在内存中存储100张图像,所有内容也都正常。
noj0wjuj2#
库巴的回答很好地描述了潜在的问题。
在我的例子中,我传递了一个
cv::Mat
作为函数的参数给图像,但是当主线程访问这个垫子时,接收图像的工作线程已经删除了它。解决方案是通过垫子的克隆。