Reputation: 91
It seems that following code is leaking memory. I checked the JVM memory utilization and it is not freeing up memory after subsequent calls. When I just run the Java as standalone it works fine for multiple calls and keeps deallocating memory just fine.
I would really appreciate any help.
jobjectArray my_obj = (jobjectArray) env->CallObjectMethod(cls, mid, qstr, pstr);
length = env->GetArrayLength(my_obj);
//printf("\nArray Length = %d \n", length);
char result[256];
const char *cstr;
int numberOfCharsInThisRow = 0;
array1 = (char **)malloc(length * sizeof(char *));
/*Check if pointer is null, if not then free its memory first*/
for(int i=0; i< length ; i++){
cstr = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(my_obj,i), 0);
numberOfCharsInThisRow = std::strlen(cstr)+1;
*(array1+i)=(char *)malloc(numberOfCharsInThisRow * sizeof(char));
std::strcpy(result, cstr);
std::strcpy(*(array1+i),result);
env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(my_obj,i), cstr);
}
env->DeleteLocalRef(my_obj);
}
//printf("\n\nDestroy JVM\n\n");
//jvm->DestroyJavaVM();
}
void libdeallocatememory(char **array1,int length) { //printf("Free Array memory \n");
for (int j=0 ;j <length ;j ++)
{
free(array1+j);
}
free(array1);
}
Upvotes: 2
Views: 3484
Reputation: 2789
You should free the array1 pointers once you are done with them. What does this function do in reality? From the functionality I understood, you are copying from the java to a c pointer. What happens next? By calling ReleaseStringUTF, you are notifying the JVM that it isnt being used in native and so can be GCed when required
Think I have found the problem. Releasing Code should be something like
for (int j=0 ;j<length; j++ )
{
free(array1[j]);
}
free(array1);
The initial allocation should be array1 = (char **)malloc(length * sizeof(int *));
The difference is int*
instead of char*
. This is because this array is just an array of pointers. Pointer size is int. The next level is in the loop where you allocate memory for your strings. It should be array1[i] = (char *)malloc(numberOfCharsInThisRow * sizeof(char));
That means initially you allocated an array of pointers. Now for each element of that arary, you are allocating the memory to hold its own string. I think even *(array1+i)
will work, but I find this more easy to read. So when you free, first you free the individual array elements you allocated, and then the entire array which you allocated initially. As an example, take a look at your current deallocate function. There is no difference between the free when j=0 and the last free. I am surprised you are not getting any crashes.
Take a look at http://c-faq.com/~scs/cclass/int/sx9b.html
Also try the following jstring myString =env->GetObjectArrayElement(my_obj,i)
; Use myString to get the UTFChars, Then call env->ReleaseStringUTFChars(mystring, cstr)
Upvotes: 1