【Android】JNI报错 non-zero capacity for nullptr pointer分析
-
背景
某天,运行Android App时程序报错。Abort message: 'JNI DETECTED ERROR IN APPLICATION: non-zero capacity for nullptr pointer: 1
in call to NewDirectByteBuffer
from ***** -
出错部分,调用了 NewDirectByteBuffer(原生JNI函数),创建了一块Buffer。pData是指针类型,dataSize是地址的大小。
cpp
byteBuffer = env->NewDirectByteBuffer(pData, dataSize);
NewDirectByteBuffer对应的实现,在art/runtime/jni/jni_internal.cc中。实现如下。
cpp
static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
if (capacity < 0) {
JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
capacity);
return nullptr;
}
if (address == nullptr && capacity != 0) {
JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
"non-zero capacity for nullptr pointer: %" PRId64, capacity);
return nullptr;
}
// At the moment, the capacity of DirectByteBuffer is limited to a signed int.
if (capacity > INT_MAX) {
JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
"buffer capacity greater than maximum jint: %" PRId64,
capacity);
return nullptr;
}
jlong address_arg = reinterpret_cast<jlong>(address);
jint capacity_arg = static_cast<jint>(capacity);
jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
WellKnownClasses::java_nio_DirectByteBuffer_init,
address_arg, capacity_arg);
return static_cast<JNIEnvExt*>(env)->self_->IsExceptionPending() ? nullptr : result;
}
通过分析上面代码,可以看出来。当传入的地址,不为NULL,且申请的Size大于0的时候。会报错non-zero capacity for nullptr 。
因为,既然申请一段空间,那么就不应该用非空的地址去申请。
- 综上
对应到出问题的地方。排查pData为NULL ,或者dataSzie不为0的情况,即可解决该问题。
cpp
byteBuffer = env->NewDirectByteBuffer(pData, dataSize);