android - 将项目添加到 C++ native 中的 ArrayList 会使单击监听器上的 android 应用程序崩溃

标签 android c++ android-ndk java-native-interface

我在 C++ 原生 JNI 中有以下方法:

extern "C" JNIEXPORT jintArray JNICALL
Java_com_haha_datastructuresample_MainActivity_arrayListFromJNI(
        JNIEnv *env,
        jobject) {

    //---------------------ArrayList-----------------
    auto *list = new ArrayList<int>();

    list->size();

    for (int i = 0; i < 100; ++i) {
        list->add(i);
    }

    list->remove(99);

    for (int i = 0; i < list->size(); ++i) {
        LOGD("arr factor:%d", list->get(i));
    }

    jintArray arr = env->NewIntArray(list->size());
    jint fill[list->size()];
    for (int i = 0; i < list->size(); i++) {
        fill[i] = list->get(i);
    }
    env->SetIntArrayRegion(arr, 0, list->size(), fill);
    return arr;
//---------------------ArrayList-----------------
}
这是 ArrayList 中的 Add 方法:
template<class E>
void ArrayList<E>::add(E e) {
    ensureCapacityInternal(index + 1);  // Increments modCount!!
    array[index++] = e;
    LOGD("add index:%d", index);
}
当我在此行添加项目时,应用程序崩溃:
array[index++] = e;
当我在 Kotlin 的 ClickListener 中调用 JNI 方法时,就会发生这种情况:
list.onItemClickListener = AdapterView.OnItemClickListener { p0, p1, p2, p3 ->
            val intent = Intent(this@MainActivity, DetailActivity::class.java)
            val res = getString(R.string.array_print, arrayListFromJNI().joinToString { it.toString() })
            intent.putExtra(EXTRA, res)
            startActivity(intent)
        }
你知道如何解决吗?
这是崩溃日志:
2020-03-24 15:56:38.254 18914-18914/com.haha.datastructuresample 

A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xffffffffc2000004 in tid 18914 (structuresample), pid 18914 (structuresample)
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: Build fingerprint: 'google/walleye/walleye:10/QQ2A.200305.002/6138846:user/release-keys'
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: Revision: 'MP1'
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: ABI: 'arm64'
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: Timestamp: 2020-03-24 17:26:56+0430
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: pid: 30948, tid: 30948, name: structuresample  >>> com.haha.datastructuresample <<<
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: uid: 10283
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xffffffffc2000004
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x0  0000007c52191bf0  x1  0000000000000001  x2  0000007b66f309f5  x3  000000005245d020
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x4  0000000000000000  x5  0000007c5216ec00  x6  0000007ff77fa3f0  x7  0000007ff77f5310
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x8  0000000000000000  x9  0000007c52191bf0  x10 ffffffffc2000004  x11 0000000000000001
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x12 0000000000000000  x13 0000000000000004  x14 0000000000000006  x15 ffffffffffffffff
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x16 0000007b66f3ebd0  x17 0000007b66f12340  x18 0000007c52c1a000  x19 0000007c5216ec00
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x20 0000000000000000  x21 0000007c5216ec00  x22 0000007ff77f5610  x23 0000007b675a717f
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x24 0000000000000004  x25 0000007c5245d020  x26 0000007c5216ecb0  x27 0000000000000001
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x28 0000007ff77f53a0  x29 0000007ff77f52a0
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     sp  0000007ff77f5270  lr  0000007b66f11884  pc  0000007b66f118ac
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG: backtrace:
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #00 pc 00000000000118ac  /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/lib/arm64/libnative-lib.so (ArrayList<int>::add(int)+116) (BuildId: 654c5d2cacdf45f6d2dfd0f27cb27227cc7b303f)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #01 pc 00000000000115fc  /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/lib/arm64/libnative-lib.so (Java_com_haha_datastructuresample_MainActivity_arrayListFromJNI+120) (BuildId: 654c5d2cacdf45f6d2dfd0f27cb27227cc7b303f)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #02 pc 000000000013f350  /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #03 pc 0000000000136334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #04 pc 00000000001450ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #05 pc 00000000002e2660  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #06 pc 00000000002dd6ec  /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+900) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #07 pc 00000000005a27b8  /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+400) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #08 pc 0000000000130914  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #09 pc 0000000000155f84  [anon:dalvik-classes.dex extracted in memory from /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/base.apk] (com.haha.datastructuresample.MainActivity.access$arrayListFromJNI)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #10 pc 00000000005a32c0  /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1136) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #11 pc 0000000000130994  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #12 pc 0000000000155ebe  [anon:dalvik-classes.dex extracted in memory from /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/base.apk] (com.haha.datastructuresample.MainActivity$onCreate$1.onItemClick+34)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #13 pc 00000000005a4fe0  /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterfaceRange+1376) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #14 pc 0000000000130d14  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface_range+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #15 pc 000000000021513c  /system/framework/framework.jar (android.widget.AdapterView.performItemClick+28)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #16 pc 00000000005a4610  /apex/com.android.runtime/lib64/libart.so (MterpInvokeSuperRange+1936) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #17 pc 0000000000130b94  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_super_range+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #18 pc 0000000000205f08  /system/framework/framework.jar (android.widget.AbsListView.performItemClick+384)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #19 pc 00000000005a0730  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1432) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #20 pc 0000000000130814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #21 pc 0000000000203190  /system/framework/framework.jar (android.widget.AbsListView$PerformClick.run+120)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #22 pc 00000000005a0730  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1432) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #23 pc 0000000000130814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #24 pc 0000000000209940  /system/framework/framework.jar (android.widget.AbsListView.onTouchUp+748)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #25 pc 00000000005a2ab8  /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+1168) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-3100

最佳答案

问题根本不在于 JNI 部分,而在于您的 ArrayList 代码:构造函数应始终填写每个字段 .您的代码在那里崩溃的原因是因为 array很可能是随机堆内存而不是 NULL .

您至少需要进行以下修改以使您的调用代码不会崩溃:

template<class E>
ArrayList<E>::ArrayList() 
  : array(nullptr), length(0) {
}

template<class E>
ArrayList<E>::ArrayList(int len) 
  : length(len) {
    array = len > 0 ? new E[len] : nullptr;
}

template<class E>
ArrayList<E>::~ArrayList() {
  delete[] array;
}

你绝对应该遵守 rule of three/five通过覆盖复制构造函数和赋值运算符。

关于android - 将项目添加到 C++ native 中的 ArrayList 会使单击监听器上的 android 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60830083/

相关文章:

android - Android 键盘消失后固定元素 (HTML) 中断了吗?

c++ - for循环的初始化超出其范围

c++ - 绝对安全的静态/运行时数字转换

android - 在 android opengl es 2 上强制重绘以超过 60 fps

android - 无法从 osx 优胜美地上的 gradle 在 Android studio 上运行 ndk-build

android - 在 Android 中使用 Scala 中的 Java 常量

android - 位置服务 onProviderEnabled 从未调用过

c++ - 如何允许在 android ndk 中使用 make_shared

android - 编写一个使用 KeyEvents 将文本插入文本字段的 Android 系统应用程序。但是扩展的 unicode 字符不可打印

c++ - C++:有关使用Stroustrup示例的移动构造函数/赋值的问题