【Android】JNI报错 non-zero capacity for nullptr pointer分析

【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是地址的大小。
byteBuffer = env->NewDirectByteBuffer(pData, dataSize);

NewDirectByteBuffer对应的实现,在art/runtime/jni/jni_internal.cc中。实现如下。

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的情况,即可解决该问题。

byteBuffer = env->NewDirectByteBuffer(pData, dataSize);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值