Release the array of string objects in JNI

165 Views Asked by At

I have tried many ways to release the string array items at the end of the processing by none of them are working. From native method, we will get the jobjectArray (which is string array in java) and once after processing, I would like to release it's resources. Here is the sample code

JNIEXPORT jintArray JNICALL Java_com_example_core_Test_perform(JNIEnv *jniEnv, jclass cls, jobjectArray args) {

    struct config _config;
    struct result _result = {0, 0, 0, 0, 0, 0, 0};

    _config.args[0] = _config.XXXX;
    int i = 1;
    int argsCount = (*jniEnv)->GetArrayLength(jniEnv, args);
    if (argsCount > 0) {
        for (; i < argsCount + 1; i++) {
            jstring jargsItem = (jstring) ((*jniEnv)->GetObjectArrayElement(jniEnv, args, i - 1));
             char *cargsItem = (char *)((*jniEnv)->GetStringUTFChars(jniEnv, jargsItem, NULL));
            _config.args[i] = cargsItem;

            //(*jniEnv)->ReleaseStringUTFChars(jniEnv, jargsItem, cargsItem);
        }
    }
    _config.args[i] = NULL;

    run(&_config, &_result);

    // Release the string array args

    jint jResult[] = {_result.a, _result.b, _result.c, _result.d, _result.e, _result.f, _result.g};

    jintArray outJNIArray = (*jniEnv)->NewIntArray(jniEnv, 7);  // allocate
    if (NULL == outJNIArray) return NULL;
    (*jniEnv)->SetIntArrayRegion(jniEnv, outJNIArray, 0 , 7, jResult);  // copy

    return outJNIArray;
}

Once the run function completes it's execution, we should release the string array. I tried to with following solution but didn't worked and giving free(): double free detected in tcache 2 Aborted error

int i =0;
for (; i< argsCount; i++) {
   jstring jargsItem = (jstring) ((*jniEnv)->GetObjectArrayElement(jniEnv, args, i));
   (*jniEnv)->ReleaseStringUTFChars(jniEnv, jargsItem, _config.args[i]);
}

I'm new to JNI. kindly help

1

There are 1 best solutions below

1
Michael On

You have a mismatch between the loop counters you use when Geting the strings, and when Releaseing them.

Change the second loop to

for (int i = 1; i < argsCount; i++) {
    jstring jargsItem = (jstring) ((*jniEnv)->GetObjectArrayElement(jniEnv, args, i - 1));
    (*jniEnv)->ReleaseStringUTFChars(jniEnv, jargsItem, _config.args[i]);
}