将项目添加到C++中的ArrayList,使Click Listener上的android应用程序崩溃



我在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;
}

并且您应该通过重写复制构造函数和赋值运算符来明确遵守3/5规则。

最新更新