所以我在 OpenCv v2.4.13.2 中为 MSER 制作了一个 JNI 包装器。
我在 Java 进程运行约 5 分钟后收到此错误:
java(658,0x7000070bb000) malloc: *** error for object 0x11921c6f0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug
这绝对是由于使用了 JNI,但我不确定究竟是什么导致了这个 malloc 错误,因为我对 C++ 不是很熟悉。我猜这是由于内存清除不当造成的,但我不确定是哪里造成的。
我文件中的相关代码:
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);
}
}
来自 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);
}
}
这似乎也只发生在我运行同一程序的多个实例时。这可能意味着它与全局 MSER mser
变量有关。
提前致谢,
基拉
最佳答案
尝试使用gdb,查看里面的back trace:
malloc_error_break
您可以在此处找到有关如何调试 JNI + Java 的信息:
http://jnicookbook.owsiak.org/recipe-No-D001/
http://jnicookbook.owsiak.org/recipe-No-D002/
您也可以在这里观看演示影片:
如果您不能使用 CLion 而必须坚持使用 gdb,请查看此处了解如何调试 Java + native 代码:
基本上,您可以做的是:
- 以 Debug模式启动 JVM
- 使用 gdb 连接到 JVM
- 在 gdb 内部将断点设置为:malloc_error_break
中断 malloc_error_break
- 一旦命中断点,查看回溯并查看在命中 malloc_error_break 之前调用了什么
享受 JNI 带来的乐趣!
关于c++ - 分配 : error for object: pointer being freed was not allocated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44088856/