opencv Mat 释放内存损坏
opencv Mat deallocation memory corruption
我正在努力解决我的opencv包装器函数的发布版本。函数代码运行良好,但在功能块完成后,会发生内存访问冲突。调试模式下不会出现此问题。段错误在释放堆时发生。
int Myfunc(Arr1D_floatHdl FeatArrHdl, IMAQ_Image *img, someparams
*Params)
{
ImageInfo *Info = NULL;
//IplImage *CVImage = NULL;
Info = (ImageInfo*)img->address;
CheckImage(Info, Info);
//CVImage = cvCreateImageHeader( cvSize(Info->xRes, Info->yRes), IPL_DEPTH_8U, 4);
//CVImage->imageData = (char*)Info->imageStart;
//CVImage->widthStep = Info->xRes*sizeof(IPL_DEPTH_8U);
cv::Mat BGRAimg = cv::Mat(Info->yRes, Info->xRes, CV_8UC4, (char*)Info->imageStart, sizeof(CV_8UC4)*Info->xRes);
//cv::Mat BGRAimg(CVImage);
//cv::Mat BGRAimg = imread( "MyImg.png", cv::IMREAD_COLOR );
cv::Mat GREYimg;
cv::cvtColor(BGRAimg, GREYimg, CV_BGR2GRAY);
这是我从用户提供的数据创建 Mat 对象的代码。我尝试首先创建 IplImage(代码中的注释版本)并使用带有 IplImage 参数的 Mat 构造函数,但遇到了同样的问题。我知道我在 Mat 构建过程中做错了什么,因为从磁盘手动加载图像不会导致问题。
创建 Mat 对象后,其所有参数都正确,图像正常。与它创建的灰色矩阵相比,它具有 refcount NULL,我读过它非常好,因为它应该保持用户数据完整。
请帮忙。
更新以提供更多信息
谢谢你的建议。我显然容易产生这样的错误,我是 C/C++ 的新手。不幸的是,访问冲突仍然存在。
这是完整的包装器函数。我试图缩小问题的范围,跳过 HOG.compute 函数,我不再得到内存损坏。最后跳过了memcpy杂技,我仍然会破坏记忆。
int GetHOGFeatures(Arr1D_floatHdl FeatArrHdl, IMAQ_Image *img, HogParams *Params) //returns -1 on HOG window parameters missmatch
{
ImageInfo *Info = NULL;
Info = (ImageInfo*)img->address;
CheckImage(Info, Info);
cv::Mat BGRAimg = cv::Mat(Info->yRes, Info->xRes, CV_8UC4, (char*)Info->imageStart, sizeof(cv::Vec4b)*Info->xRes);
cv::Mat GREYimg;
cv::cvtColor(BGRAimg, GREYimg, CV_BGRA2GRAY);
//set params into hog object
cv::HOGDescriptor hog;
hog.winSize = cv::Size(Params->winsize_width, Params->winsize_height);
hog.blockSize = cv::Size(Params->blocksize_width, Params->blocksize_height);
hog.blockStride = cv::Size(Params->blockstride_x, Params->blockstride_y);
hog.cellSize = cv::Size(Params->cellsize_width, Params->cellsize_height);
hog.nbins = Params->nBins;
hog.derivAperture = Params->derivAperture;
hog.winSigma = Params->win_sigma;
hog.L2HysThreshold = Params->threshold_L2hys;
hog.gammaCorrection = (Params->gammaCorrection != 0);
MgErr error = mgNoErr;
cv::vector<float> ders;
cv::vector<cv::Point> locations;
try
{
//winstride - step of window
//padding - borderpadding
//raises exception with incorrect params ... todo replace trycatch with paramchecking
hog.compute(GREYimg, ders, cv::Size(Params->winstride_x, Params->winstride_y), cv::Size(0,0), locations);
}
catch(...)
{
return -1;
}
//copy out the data into LabView
error = DSSetHandleSize(FeatArrHdl, sizeof(int32_t) + ders.size()*sizeof(float));
memcpy((*FeatArrHdl)->Arr, ders.data(), sizeof(float)*ders.size());
(*FeatArrHdl)->dimSize = ders.size();
return error;
}
我使用以下参数运行此函数:
窗户尺寸 32区块大小 16细胞大小 8阻止步幅 8
车窗步幅 32
其余参数是默认参数。
我决定在构建后包括 Mat 对象的外观,我希望它能有所帮助。
这是从用户数据构建的 BGRA。应该是640*640 BGRA
- BGRAimg {flags=1124024344 dims=2 行=640 ...} cv::垫子 标志1124024344 int 暗淡 2 整数 第 640 行 int 科尔斯 640 国际
- 数据0x12250040"E9%"无符号字符 * 101 'e' 无符号字符
- 参考文献 0x00000000 int * CXX0030:错误:无法计算表达式
- 数据启动0x12250040"E9%"无符号字符 * 101 'e' 无符号字符
- 数据结束 0x123e0040 " 无符号字符 * 0 个无符号字符
- 数据限制 0x123e0040 " 无符号字符 * 0 个无符号字符
- 分配器 0x00000000 cv::分配器 * __vfptr CXX0030:错误:无法计算表达式
- size {p=0x0012f44c } cv::Mat::MSize
- p 0x0012f44c int * 640 国际
- step {p=0x0012f474 buf=0x0012f474 } cv::Mat::MStep
- p 0x0012f474 无符号整数 * 2560 无符号整数
- BUF 0x0012f474 无符号 int [2] [0] 2560 无符号 int [1] 4 无符号整数
以及进入 HOG 描述符计算器的灰色图像
- GREYimg {flags=1124024320 dims=2 行=640 ...} cv::垫子 标志1124024320 int 暗淡 2 整数 第 640 行 int 科尔斯 640 国际
- 参考文献 0x0c867ff0 int * 1 整数
- 数据结束 0x0c867ff0 " 无符号字符 * 1 个无符号字符
- 数据限制 0x0c867ff0 " 无符号字符 * 1 个无符号字符
- 分配器 0x00000000 cv::分配器 * __vfptr CXX0030:错误:无法计算表达式
- size {p=0x0012f40c } cv::Mat::MSize
- p 0x0012f40c int * 640 国际
- step {p=0x0012f434 buf=0x0012f434 } cv::Mat::MStep
- p 0x0012f434 无符号整数 * 640 无符号整数
- 布夫 0x0012f434 无符号 [2] [0] 640 无符号 int [1] 1 个无符号整数
我不得不省略数据和数据启动字段,因为与 BGRA 图像不同,MSVS 实际上在其中显示了一些数据。
UPDATE2
在项目属性中更改了多线程的多线程 DLL,问题就消失了。
即使我使用这样的代码,问题仍然存在:
int dim = 32;
BYTE *mydata = NULL;
mydata = (BYTE*)malloc(sizeof(BYTE)*dim*dim);
Mat img;
img = Mat(Size(dim,dim), CV_8U, mydata, dim*sizeof(BYTE));
这可能表明我的代码不是原因,这有点 opencv x Windows 运行时问题,还是我只是隐藏了问题?
UPDATE3
在阅读了一些关于微软运行时的内容后,我决定检查我的opencv是如何构建的,它使用的是/MD,而我使用的是/MT构建的。我希望这是原因。
不像您期望的那样工作:
sizeof(CV_8UC4)*Info->xRes
CV_8UC4是一个枚举,而不是一个类型,你不能在这里使用 sizeof()。
如果数据是连续的,则可能只是完全跳过步幅参数,或者:
sizeof(Vec4b)*Info->xRes
另一件事:
您的 BGRAimg 有 4 个通道,对吧? 所以,使用
cv::cvtColor(BGRAimg, GREYimg, CV_BGRA2GRAY);
相反
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 正在调试 malloc():新内存损坏
- 仅特定内核计数上的 MPI 内存损坏
- C++程序错误:malloc():内存损坏
- 内存地址是否由于未对齐的内存地址而损坏?
- 调用std::函数成员时内存损坏
- 通过分配大量内存来跟踪堆损坏
- C++ 内存损坏检测
- 由于标头中的 #define 不匹配而导致内存损坏
- C STD ::线程中的种族状况或内存损坏
- malloc()内存损坏仅通过为特定数量编写int数组
- 字符串标记化期间的内存损坏
- 从检测到 glibc 正常退出 - malloc():内存损坏
- 放置在外部 DLL 中的类中的字符串数据的内存损坏
- std :: string ::擦除会导致内存损坏
- 编译器如何检测内存损坏
- 获得MAC地址的代码似乎会损坏内存,但仅在发布构建中而不是调试构建
- Visual Studio在使用sockaddr_storage时会损坏内存
- 构造函数中的字段初始化会损坏内存
- 字符串结束字符会损坏内存吗?缓冲区[大小]='\0';