0

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.

1 Answer 1

1

Probably you have corrupted memory somewhere, but not in the code above. Usage of cv::Mat::zeros looks fine.

Use Valgrind to find the reason of the problem.

UPDATE

I solved my issues by replacing m.at=someint with m.at=someint in the previous lines of my code

It works because your Mat m is not represented by double type. m should have type CV_64F or similar to access double elements. Actually your Mat m type is CV_8U, it corresponds to uchar you have used in your fix.

To change type of Mat m you can use convertTo method.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you, I tried Valgrind, it's exactly what I need for. I'll update my post with further information (or maybe the solution?)
@RomainMartin I'm sure problem is not in gKernel function. Looks like memory was corrupted before gsmooth execution. E.g. check picture loading functionality.
I trust you, but I can't find where there can be any issue. Picture loading functionality looks fine, it's only called one time at the begining, I tried to replace the image loaded by a ones-filled matrix, but still have the same results... I will check again and post if I find any clue.
I solved my issues by replacing m.at<double>=someint with m.at<uchar>=someint in the previous lines of my code. However I don't understand why it's working with uchar and not with double, I don't need double matrix in most of the cases so it was no use to deal . with m<double> except increasing the size of my pictures. But in some parts I need to have, at least, floatting numbers, so I hope i won't have corrupted memory issue. I'll let my question unanswered for some days if someone can explain why it didn't work. Anyway thanks Nikita for your help, you were right.
@RomainMartin Looks like the reason is clear for me. Please check the answer update
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.