I'm facing a sysmalloc error using opencv. When I debug I find that the error occurs here:
sm = cv::Mat::zeros(h,w,img.type());
Where h and w are respectively img rows and w cols. I displayed them and they were ok. Here is the whole function:
cv::Mat gsmooth(cv::Mat img,int sigma,int radius,std::string methode)
{
cv::Mat sm;
std::vector<double> hcol;
std::vector<double> hrow;
if(sigma == NULL)
{
sigma =1;
}
if(radius == NULL)
{
radius = ceil(2.5*sigma);
}
if(methode.c_str()==NULL)
{
methode ="none";
}
if(sigma == 0)
{
sm = img;
}
else
{
hcol= gKernel(2*radius+1,sigma);
hrow= gKernel(2*radius+1,sigma);
int h=img.rows;
int w=img.cols;
int c=img.channels();
switch (c)
{
case 1:
sm= cv::Mat::zeros(h,w,img.type());
break;
case 2:
sm= cv::Mat::zeros(h,w,CV_32SC2);
break;
default:
sm= cv::Mat::zeros(h,w,CV_32SC3);
}
if(!methode.compare(std::string("mirror")))
{
cv::Mat mattmp=mirror(img,radius,radius);
sm=conv2(mattmp,hcol,hrow);
int ma=img.rows;
int na=img.cols;
int nb=hcol.size();
int mb=hrow.size();
sm=sm.rowRange((mb-1)/2,(mb-1)/2+ma).colRange((nb-1)/2,(nb-1)/2+na);
}
else
{
cv::Mat sm_;
sm_=conv2(img,hcol,hrow);
int H=sm.rows;
int W=sm.cols;
int h=img.rows;
int w=img.cols;
int y=ceil(H/h);
int x=ceil(W/w);
sm=sm.rowRange(y,y+h).colRange(x,x+w);
}
}
hcol.clear();
hrow.clear();
return(sm);
}
The function is call by another .cpp with a cv::Mat img, two int and "mirror" or "none". The arguments seem correct: the img matrix is correctly loaded and the other are only int.
The full error is: *malloc.c:2372: sysmalloc: Assertion '(old_top== (((mbinptr) (((char *) &((av)->bins[((1) - 1)*2)) -__builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk,fd_nextsize))+((2*(sizeof(size_t))) -1)) & ~((2*sizeof(size_t))) -1)))&& ((old_top)-> size & 0x1) && ((unsigned long) old_end & pagemask) ==0)' failed.*
I'm on ubuntu 14.04.5 using Qt 5.2, gcc 4.6 and g++ 4.4 and i've to use opencv 2.4.13 due to compatibility issues with braid lib.
I'm sure that my error is something stupid, maybe I can't declare a matrix of zero like this but I don't know how to do otherwise and I didn't find any topic relatives with this issue.
In general I'm quite stuck with malloc issue using opencv. Most of the times, i'm using function getting a cv::Mat in argument and using it to return a new matrix declared inside the function, like this:
cv::Mat function somefunction(cv::Mat img, some arguments)
{
cv::Mat res;
//operations
return(res);
}
and I call the function like this: new_img=some_function(img, some_arguments);
I wonder if it's the right way to do?
I hope I've been specific enough, don't hesitate if you need more information.
EDIT: Using Valgrind I found that the issue occurs when I try to use gKernel.
In fact gsmooth is call two times, the first one everything is ok and the crash occurs during the second call. Valgrind pointed a SIGSEGV error at the first line of the function: std::vector<double> kernel(size);
Here is the entire function:
std::vector<double> gKernel(int size, float sigma)
{
std::vector<double>kernel(size);
double r,s =2.0* sigma * sigma;
double sum=0.0;
int radius=(size -1)/2;
int index=0;
for(int y=-radius; y<=radius;y++)
{
r=sqrt(y*y);
kernel[index]=(exp(-(r*r)/s))/(sqrt(2*M_PI*s));
sum+=kernel[index];
index++;
}
for(int i=0;i<size;i++)
{
kernel[i]/=sum;
}
return(kernel);
}
I don't understand why declaring a vector may cause a Segfault? As you can see in my gsmooth function, gKernel is call with size = 2*radius +1 and sigma is equal to 60 in the first call and 50 to the second one.
At least I learned that I shouldn't copy cv::Mat with '=' but rather with clone or copyTo to avoid jumbling up pixels'pointers.