简体   繁体   中英

malloc: error for object: pointer being freed was not allocated

so I made a JNI wrapper for an MSER in OpenCv v2.4.13.2.

I receive this error after about 5 minutes leaving the Java process running:

java(658,0x7000070bb000) malloc: *** error for object 0x11921c6f0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

This is most definitely from the use of JNI, but I'm unsure of what exactly is causing this malloc error as I am not terribly familiar with C++. I'm guessing it's due to improper memory clearing, but am unsure of where.

Relevant code from my file:

MSER mser; // Global variable so that pointer useable by Java can be created

JNIEXPORT jlong JNICALL Java_org_opencv_features2d_MSER_create_11(JNIEnv* env, jclass cls, jint delta, jint min_area, jint max_area, jdouble max_variation, jdouble min_diversity, jint max_evolution, jdouble area_threshold, jdouble min_margin, jint edge_blur_size)
{
    static const char method_name[] = "MSSR::create_1";

    //LOGD("%s", method_name);

    mser = MSER::MSER(delta, min_area, max_area, max_variation, min_diversity, max_evolution, area_threshold, min_margin, edge_blur_size);

    return (jlong) &mser;
}

JNIEXPORT void JNICALL Java_org_opencv_features2d_MSER_detect_14(JNIEnv* env, jobject thiz, jlong self, jlong image_addr, jlong msers_addr, jlong mask_addr)
{
    static const char method_name[] = "MSSR::detect_4";

    try {
        //LOGD("%s", method_name);
        MSER* me = (MSER*) self;
        Mat image = *(Mat*) image_addr;
        vector<vector<Point> > msers; // List<MatOfPoint> -> Mat -> vector<vector<Point> >
        Mat mask = *(Mat*) mask_addr;
        me->operator()(image, msers, mask);
        vector_vector_Point_to_Mat(msers, *(Mat*)msers_addr); // Store vector data in Mat dummy to be converted to List<MatOfPoint>
    }
    catch (const exception &e) {
        throwJavaException(env, &e, method_name);
    }
    catch (...) {
        throwJavaException(env, 0, method_name);
    }
}

And from converters.cpp:

#define CHECK_MAT(cond) if(!(cond)){ return; }

void vector_vector_Point_to_Mat(std::vector< std::vector< Point > >& vv_pt, Mat& mat)
{
    std::vector<Mat> vm;
    vm.reserve( vv_pt.size() );
    for(size_t i=0; i<vv_pt.size(); i++)
    {
        Mat m;
        vector_Point_to_Mat(vv_pt[i], m);
        vm.push_back(m);
    }
    vector_Mat_to_Mat(vm, mat);
}

void vector_Mat_to_Mat(std::vector<cv::Mat>& v_mat, cv::Mat& mat)
{
    int count = (int)v_mat.size();
    mat.create(count, 1, CV_32SC2);
    for(int i=0; i<count; i++)
    {
        long long addr = (long long) new Mat(v_mat[i]);
        mat.at< Vec<int, 2> >(i, 0) = Vec<int, 2>(addr>>32, addr&0xffffffff);
    }
}

This also only seems to happen when I have multiple instances of the same program running. That probably means it has something to do with the global MSER mser variable.

Thanks in advance,
Kira

Try to use gdb and check the back trace inside:

malloc_error_break

You can find information on how to debug JNI + Java here:

http://jnicookbook.owsiak.org/recipe-No-D001/

http://jnicookbook.owsiak.org/recipe-No-D002/

You can also take a look at demo movie here:

https://youtu.be/8Cjeq4l5COU

In case you can't use CLion and you have to stick to gdb, take a look here on how to debug Java + native code:

http://www.owsiak.org/?p=2095

Basically, what you can do is to:

  • start JVM in debug mode
  • attach to JVM using gdb
  • inside gdb set breakpoint to: malloc_error_break

break malloc_error_break

  • once breakpoint is hit, take a look at back trace and see what was called just before malloc_error_break was hit

Have fun with JNI!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM