JNI中C++ vector<int>转jintArray输出垃圾值如何解决
问题根因
你的代码有两个核心错误:
- 调用
GetIntArrayElements获取到的是JNI分配的临时元素指针,修改完指针指向的内存后,必须调用ReleaseIntArrayElements提交修改并释放临时指针,否则所有修改都不会同步到jintArray对象上,还会触发内存泄漏。 jintArray是Java数组对象的JNI引用,不是C/C++层面的原生数组指针,直接写jarray[i]属于非法的未定义内存访问,读到的自然是0或者随机垃圾值,完全不能用这种方式读取Java数组内容。
正确实现代码
标准指针拷贝写法
#include <vector> #include <jni.h> using namespace std; jintArray convertVectorToJintArray(JNIEnv* env, const vector<int>& input) { // 按输入vector长度创建空jintArray jintArray result = env->NewIntArray(input.size()); if (result == nullptr) return nullptr; if (input.empty()) return result; // 获取可写的底层元素指针 jint* elements = env->GetIntArrayElements(result, nullptr); if (elements == nullptr) { env->DeleteLocalRef(result); return nullptr; } // 逐元素拷贝数据 for (int i = 0; i < input.size(); ++i) { elements[i] = static_cast<jint>(input[i]); } // 关键步骤:提交修改到Java数组,释放临时指针 // 最后一个参数传0代表同步修改+释放elements内存 env->ReleaseIntArrayElements(result, elements, 0); return result; } // 调用示例 void testCall(JNIEnv* env) { vector<int> vec_data = {1,2,3,4,5}; jintArray j_arr = convertVectorToJintArray(env, vec_data); // 后续正常使用j_arr即可 }
更简洁的区间拷贝写法
如果不需要对元素做额外处理,直接用SetIntArrayRegion可以省去手动申请、释放指针的步骤,代码更短也不容易出错:
jintArray convertVectorToJintArrayFast(JNIEnv* env, const vector<int>& input) { jintArray result = env->NewIntArray(input.size()); if (result == nullptr || input.empty()) return result; // 直接将vector内存块的内容拷贝到jintArray的指定区间 env->SetIntArrayRegion(result, 0, input.size(), reinterpret_cast<const jint*>(input.data())); return result; }
注意事项
- 所有通过
Get<Type>ArrayElements系列方法拿到的原生指针,必须和Release<Type>ArrayElements配对调用,否则会出现修改不生效、内存泄漏、JVM局部引用表溢出等问题。 - 所有JNI引用类型(包括
jintArray、jobject、jstring等)都不能直接做C/C++层面的下标访问、指针解引操作,必须通过JNI提供的标准接口读写内容。
内容的提问来源于stack exchange,提问作者Newbie
相关产品推荐
相关产品推荐

