I have a library in c++ and I am writing JNI wrapper functions to allow me to call it from JAVA. I have got a lot of different functions working but I am having a problem with one in particular.
The function I am trying to wrap looks like:
void Set_Name(std::string invar)
I have matching calls to GetStringUTFChars and ReleaseStringUTFChars as follows:
JNIEXPORT void JNICALL Java_com_metcarob_mys_javaapi_a_1SM_1D_1Orginisation_Set_1Name
(JNIEnv *p_jEnv, jobject p_jObj, jlong p_nat, jstring invar) {
SM_D_Orginisation* p_SMD = (SM_D_Orginisation*) p_nat;
const char *pPp_invar2 = p_jEnv->GetStringUTFChars( invar, NULL );
if (NULL==pPp_invar2) return;
std::string *pPp_invar = new std::string(pPp_invar2);
p_SMD->Set_Name(*pPp_invar);
pPp_invar2 = pPp_invar->c_str();
p_jEnv->ReleaseStringUTFChars(invar, pPp_invar2);
SAFE_DELETE(pPp_invar);
}
I am getting an invalid pointer exception when I run this from Java:
*** glibc detected *** /home/robert/Oracle/Middleware/jdk160_21/bin/java: free(): invalid pointer: 0x0841a744 ***
======= Backtrace: =========
/lib32/libc.so.6(+0x6b511)[0xf7637511]
/lib32/libc.so.6(+0x6ce1b)[0xf7638e1b]
/lib32/libc.so.6(cfree+0x6d)[0xf763bf8d]
/home/robert/Oracle/Middleware/jdk160_21/jre/lib/i386/client/libjvm.so(+0x34fc8c)[0xf703bc8c]
/home/robert/Oracle/Middleware/jdk160_21/jre/lib/i386/client/libjvm.so(+0x25139a)[0xf6f3d39a]
/home/robert/Encrypted/Projects/Scout_Management/smbackend/DEBUG/libjavaapi.so(_ZN7JNIEnv_21ReleaseStringUTFCharsEP8_jstringPKc+0x27)[0xe02475c9]
/home/robert/Encrypted/Projects/Scout_Management/smbackend/DEBUG/libjavaapi.so(Java_com_metcarob_mys_javaapi_a_1SM_1D_1Orginisation_Set_1Name+0xd8)[0xe0245467]
[0xf4c0105d]
If I remove the call to ReleaseStringURFChars it works without a problem. Documentation states that I must call ReleaseStringUTFChars for every call I make to GetStringUTFChars to prevent memory leaks.
I have no idea what I am doing wrong or what I should be checking.
Can anyone assist?
Thanks
Robert
You first acquire the pointer with
But then you reassign the pointer with
You must first first release the memory, then reassign the pointer.
Also, you don’t need to allocate
pPp_invarwithnewand then delete it, a simplep_SMD->Set_Name(pPp_invar2);should suffice.